From 39816efa3b98341941980a7ff5ebd8cc042e28e4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 19 Apr 2019 12:57:08 -0700 Subject: [PATCH 001/676] Test invoking a callback-based RPC under lock --- .../end2end/client_callback_end2end_test.cc | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 821fcc2da6d..da2ce854703 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -374,6 +374,34 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { SendRpcs(1, false); } +TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { + MAYBE_SKIP_TEST; + ResetStub(); + std::mutex mu; + std::condition_variable cv; + bool done; + EchoRequest request; + request.set_message("Hello locked world."); + EchoResponse response; + ClientContext cli_ctx; + { + std::lock_guard l(mu); + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&mu, &cv, &done, &request, &response](Status s) { + std::lock_guard l(mu); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(request.message(), response.message()); + done = true; + cv.notify_one(); + }); + } + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { MAYBE_SKIP_TEST; ResetStub(); From 72312daadf571adaef351a482a30f6afc1b94e2c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 19 Apr 2019 12:57:32 -0700 Subject: [PATCH 002/676] Move callback-based API to use Executors over ApplicationExecutionCtx --- src/core/lib/surface/completion_queue.cc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 7d679204bac..9f2a6b4783a 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -814,6 +814,11 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, GRPC_ERROR_UNREF(error); } +static void functor_callback(void* arg, grpc_error* error) { + auto* functor = static_cast(arg); + (*functor).functor_run(callback, error == GRPC_ERROR_NONE ? true : false); +} + /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -822,7 +827,6 @@ static void cq_end_op_for_callback( GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); - bool is_success = (error == GRPC_ERROR_NONE); if (grpc_api_trace.enabled() || (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { @@ -847,10 +851,13 @@ static void cq_end_op_for_callback( cq_finish_shutdown_callback(cq); } - GRPC_ERROR_UNREF(error); - auto* functor = static_cast(tag); - grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, is_success); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); + + GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -1334,7 +1341,11 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(functor_callback, callback, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); + } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 56e34854caeefbbbbae0cd4c9e3649a01d466153 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 19 Apr 2019 13:52:55 -0700 Subject: [PATCH 003/676] Fix review comments and clang fixes. --- src/core/lib/surface/completion_queue.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 9f2a6b4783a..29dd2101e10 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -34,6 +34,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" @@ -816,7 +817,7 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, static void functor_callback(void* arg, grpc_error* error) { auto* functor = static_cast(arg); - (*functor).functor_run(callback, error == GRPC_ERROR_NONE ? true : false); + functor->functor_run(functor, error == GRPC_ERROR_NONE); } /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ @@ -853,8 +854,9 @@ static void cq_end_op_for_callback( auto* functor = static_cast(tag); GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); @@ -1342,10 +1344,10 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(functor_callback, callback, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_CLOSURE_CREATE( + functor_callback, callback, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_NONE); - } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 358e2543be0220051b237033340eeb56e07e54c7 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Mon, 22 Apr 2019 18:22:28 +0000 Subject: [PATCH 004/676] Add 1.19 and 1.20 to interop matrix --- tools/interop_matrix/client_matrix.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 67b6832c8b2..1a8b8ef248e 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -213,6 +213,8 @@ LANG_RELEASE_MATRIX = { ReleaseInfo(patch=[ 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', ])), + ('v1.19.0', ReleaseInfo()), + ('v1.20.0', ReleaseInfo()), # TODO: https://github.com/grpc/grpc/issues/18262. # If you are not encountering the error in above issue # go ahead and upload the docker image for new releases. From f3911e7ff17e58d57b01132ac6351e837de877ab Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 22 Apr 2019 15:37:54 -0700 Subject: [PATCH 005/676] Fix the completion queue tests for the new behavior --- test/core/surface/completion_queue_test.cc | 46 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 7c3630eaf18..214d673cdf6 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -365,10 +366,19 @@ static void test_callback(void) { GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING}; grpc_completion_queue_attributes attr; unsigned i; + static gpr_mu mu, shutdown_mu; + static gpr_cv cv, shutdown_cv; + static int cb_counter; + gpr_mu_init(&mu); + gpr_mu_init(&shutdown_mu); + gpr_cv_init(&cv); + gpr_cv_init(&shutdown_cv); LOG_TEST("test_callback"); + gpr_mu_lock(&shutdown_mu); bool got_shutdown = false; + gpr_mu_unlock(&shutdown_mu); class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: ShutdownCallback(bool* done) : done_(done) { @@ -376,7 +386,11 @@ static void test_callback(void) { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); + gpr_mu_unlock(&shutdown_mu); + // Signal when the shutdown callback is completed. + gpr_cv_signal(&shutdown_cv); } private: @@ -391,9 +405,11 @@ static void test_callback(void) { for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { int sumtags = 0; int counter = 0; + gpr_mu_lock(&mu); + cb_counter = 0; + gpr_mu_unlock(&mu); { // reset exec_ctx types - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; attr.cq_polling_type = polling_types[pidx]; cc = grpc_completion_queue_create( @@ -409,7 +425,13 @@ static void test_callback(void) { int ok) { GPR_ASSERT(static_cast(ok)); auto* callback = static_cast(cb); + gpr_mu_lock(&mu); + cb_counter++; *callback->counter_ += callback->tag_; + if (cb_counter == GPR_ARRAY_SIZE(tags)) { + gpr_cv_signal(&cv); + } + gpr_mu_unlock(&mu); grpc_core::Delete(callback); }; @@ -429,12 +451,34 @@ static void test_callback(void) { nullptr, &completions[i]); } + gpr_mu_lock(&mu); + while (cb_counter != GPR_ARRAY_SIZE(tags)) { + // Wait for all the callbacks to complete. + gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&mu); + shutdown_and_destroy(cc); + + gpr_mu_lock(&shutdown_mu); + while (!got_shutdown) { + // Wait for the shutdown callback to complete. + gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&shutdown_mu); } + + gpr_mu_lock(&mu); + // Run the assertions to check if the test ran successfully. GPR_ASSERT(sumtags == counter); GPR_ASSERT(got_shutdown); + gpr_mu_unlock(&mu); got_shutdown = false; } + gpr_mu_destroy(&mu); + gpr_mu_destroy(&shutdown_mu); + gpr_cv_destroy(&cv); + gpr_cv_destroy(&shutdown_cv); } struct thread_state { From 4f4476e00f61b14a8f1141a0ba743215e39d88b2 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 10:17:13 -0700 Subject: [PATCH 006/676] Make the exector to LONG from SHORT --- src/core/lib/surface/completion_queue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 29dd2101e10..afd046596ef 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -856,7 +856,7 @@ static void cq_end_op_for_callback( GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)), GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); @@ -1346,7 +1346,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, callback, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)), GRPC_ERROR_NONE); } From 4eca064dcccebf70f44f023f1d2ac552614c2cf1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Apr 2019 08:49:48 -0700 Subject: [PATCH 007/676] Implement interceptor --- src/objective-c/GRPCClient/GRPCCall.h | 30 +- src/objective-c/GRPCClient/GRPCCall.m | 388 +++++------- src/objective-c/GRPCClient/GRPCCallOptions.h | 39 ++ src/objective-c/GRPCClient/GRPCCallOptions.m | 32 + src/objective-c/GRPCClient/GRPCInterceptor.h | 152 +++++ src/objective-c/GRPCClient/GRPCInterceptor.m | 222 +++++++ .../GRPCClient/private/GRPCCall+V2API.h | 18 + .../GRPCClient/private/GRPCCallInternal.h | 25 + .../GRPCClient/private/GRPCCallInternal.m | 324 ++++++++++ src/objective-c/ProtoRPC/ProtoRPC.h | 27 + src/objective-c/ProtoRPC/ProtoRPC.m | 34 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 296 ++++++++- src/objective-c/tests/InteropTests.m | 577 +++++++++++++++++- 13 files changed, 1925 insertions(+), 239 deletions(-) create mode 100644 src/objective-c/GRPCClient/GRPCInterceptor.h create mode 100644 src/objective-c/GRPCClient/GRPCInterceptor.m create mode 100644 src/objective-c/GRPCClient/private/GRPCCall+V2API.h create mode 100644 src/objective-c/GRPCClient/private/GRPCCallInternal.h create mode 100644 src/objective-c/GRPCClient/private/GRPCCallInternal.m diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 6669067fbff..1a941571951 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -169,11 +169,23 @@ extern NSString *const kGRPCTrailersKey; - (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; /** + * This method is deprecated and does not work with interceptors. To use GRPCCall2 interface with + * interceptor, implement didReceiveData: instead. To implement an interceptor, please leave this + * method unimplemented and implement didReceiveData: method instead. If this method and + * didReceiveRawMessage are implemented at the same time, implementation of this method will be + * ingored. + * * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. */ - (void)didReceiveRawMessage:(nullable NSData *)message; +/** + * Issued when a decompressed message is received from the server. The message is decompressed, and + * deserialized if a marshaller is provided to the call. + */ +- (void)didReceiveData:(id)data; + /** * Issued when a call finished. If the call finished successfully, \a error is nil and \a * trainingMetadata consists any trailing metadata received from the server. Otherwise, \a error @@ -183,6 +195,12 @@ extern NSString *const kGRPCTrailersKey; - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; +/** + * Issued when flow control is enabled for the call and a message written with writeData: method of + * GRPCCall2 is passed to gRPC core with SEND_MESSAGE operation. + */ +- (void)didWriteData; + @end /** @@ -253,9 +271,9 @@ extern NSString *const kGRPCTrailersKey; - (void)cancel; /** - * Send a message to the server. Data are sent as raw bytes in gRPC message frames. + * Send a message to the server. The data is subject to marshaller serialization and compression. */ -- (void)writeData:(NSData *)data; +- (void)writeData:(id)data; /** * Finish the RPC request and half-close the call. The server may still send messages and/or @@ -263,6 +281,14 @@ extern NSString *const kGRPCTrailersKey; */ - (void)finish; +/** + * Tell gRPC to receive the next N gRPC message from gRPC core. + * + * This method should only be used when flow control is enabled. When flow control is not enabled, + * this method is a no-op. + */ +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + /** * Get a copy of the original call options. */ diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 245a5e9ba02..fb4dbdb5d71 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -17,8 +17,9 @@ */ #import "GRPCCall.h" - #import "GRPCCall+OAuth2.h" +#import "GRPCInterceptor.h" +#import "GRPCCallOptions.h" #import #import @@ -27,7 +28,6 @@ #include #include -#import "GRPCCallOptions.h" #import "private/GRPCChannelPool.h" #import "private/GRPCCompletionQueue.h" #import "private/GRPCConnectivityMonitor.h" @@ -37,6 +37,8 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" +#import "private/GRPCCall+V2API.h" +#import "private/GRPCCallInternal.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -57,11 +59,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; @property(atomic, strong) NSDictionary *responseHeaders; @property(atomic, strong) NSDictionary *responseTrailers; -- (instancetype)initWithHost:(NSString *)host - path:(NSString *)path - callSafety:(GRPCCallSafety)safety - requestsWriter:(GRXWriter *)requestsWriter - callOptions:(GRPCCallOptions *)callOptions; +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; @end @@ -89,30 +87,23 @@ const char *kCFStreamVarName = "grpc_cfstream"; @end +/** + * This class acts as a wrapper for interceptors + */ @implementation GRPCCall2 { - /** Options for the call. */ - GRPCCallOptions *_callOptions; /** The handler of responses. */ - id _handler; + id _responseHandler; - // Thread safety of ivars below are protected by _dispatchQueue. + /** + * Points to the first interceptor in the interceptor chain. + */ + id _firstInterceptor; /** - * Make use of legacy GRPCCall to make calls. Nullified when call is finished. + * The actual call options being used by this call. It is different from the user-provided + * call options when the user provided a NULL call options object. */ - GRPCCall *_call; - /** Flags whether initial metadata has been published to response handler. */ - BOOL _initialMetadataPublished; - /** Streaming call writeable to the underlying call. */ - GRXBufferedPipe *_pipe; - /** Serial dispatch queue for tasks inside the call. */ - dispatch_queue_t _dispatchQueue; - /** Flags whether call has started. */ - BOOL _started; - /** Flags whether call has been canceled. */ - BOOL _canceled; - /** Flags whether call has been finished. */ - BOOL _finished; + GRPCCallOptions *_actualCallOptions; } - (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions @@ -134,30 +125,41 @@ const char *kCFStreamVarName = "grpc_cfstream"; if ((self = [super init])) { _requestOptions = [requestOptions copy]; - if (callOptions == nil) { - _callOptions = [[GRPCCallOptions alloc] init]; + _callOptions = [callOptions copy]; + if (!_callOptions) { + _actualCallOptions = [[GRPCCallOptions alloc] init]; } else { - _callOptions = [callOptions copy]; + _actualCallOptions = [callOptions copy]; } - _handler = responseHandler; - _initialMetadataPublished = NO; - _pipe = [GRXBufferedPipe pipe]; - // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 - if (@available(iOS 8.0, macOS 10.10, *)) { - _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + _responseHandler = responseHandler; + + // Initialize the interceptor chain + GRPCCall2Internal *internalCall = [[GRPCCall2Internal alloc] init]; + id nextInterceptor = internalCall; + GRPCInterceptorManager *nextManager = nil; + NSArray *interceptorFactories = _actualCallOptions.interceptorFactories; + if (interceptorFactories.count == 0) { + [internalCall setResponseHandler:_responseHandler]; } else { -#else - { -#endif - _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { + GRPCInterceptorManager *manager = [[GRPCInterceptorManager alloc] initWithNextInerceptor:nextInterceptor]; + GRPCInterceptor *interceptor = [interceptorFactories[i] createInterceptorWithManager:manager]; + NSAssert(interceptor != nil, @"Failed to create interceptor"); + if (interceptor == nil) { + return nil; + } + if (i == (int)interceptorFactories.count - 1) { + [internalCall setResponseHandler:interceptor]; + } else { + [nextManager setPreviousInterceptor:interceptor]; + } + nextInterceptor = interceptor; + nextManager = manager; + } + + [nextManager setPreviousInterceptor:_responseHandler]; } - dispatch_set_target_queue(_dispatchQueue, responseHandler.dispatchQueue); - _started = NO; - _canceled = NO; - _finished = NO; + _firstInterceptor = nextInterceptor; } return self; @@ -170,197 +172,65 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)start { - GRPCCall *copiedCall = nil; + id copiedFirstInterceptor; @synchronized(self) { - NSAssert(!_started, @"Call already started."); - NSAssert(!_canceled, @"Call already canceled."); - if (_started) { - return; - } - if (_canceled) { - return; - } - - _started = YES; - if (!_callOptions) { - _callOptions = [[GRPCCallOptions alloc] init]; - } - - _call = [[GRPCCall alloc] initWithHost:_requestOptions.host - path:_requestOptions.path - callSafety:_requestOptions.safety - requestsWriter:_pipe - callOptions:_callOptions]; - [_call setResponseDispatchQueue:_dispatchQueue]; - if (_callOptions.initialMetadata) { - [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; - } - copiedCall = _call; + copiedFirstInterceptor = _firstInterceptor; + } + GRPCRequestOptions *requestOptions = [_requestOptions copy]; + GRPCCallOptions *callOptions = [_actualCallOptions copy]; + if ([copiedFirstInterceptor respondsToSelector:@selector(startWithRequestOptions:callOptions:)]) { + dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ + [copiedFirstInterceptor startWithRequestOptions:requestOptions + callOptions:callOptions]; + }); } - - void (^valueHandler)(id value) = ^(id value) { - @synchronized(self) { - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - if (value) { - [self issueMessage:value]; - } - } - } - }; - void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { - @synchronized(self) { - if (self->_handler) { - if (!self->_initialMetadataPublished) { - self->_initialMetadataPublished = YES; - [self issueInitialMetadata:self->_call.responseHeaders]; - } - [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; - } - // Clearing _call must happen *after* dispatching close in order to get trailing - // metadata from _call. - if (self->_call) { - // Clean up the request writers. This should have no effect to _call since its - // response writeable is already nullified. - [self->_pipe writesFinishedWithError:nil]; - self->_call = nil; - self->_pipe = nil; - } - } - }; - id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; - [copiedCall startWithWriteable:responseWriteable]; } - (void)cancel { - GRPCCall *copiedCall = nil; + id copiedFirstInterceptor; @synchronized(self) { - if (_canceled) { - return; - } - - _canceled = YES; - - copiedCall = _call; - _call = nil; - _pipe = nil; - - if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { - dispatch_async(_dispatchQueue, ^{ - // Copy to local so that block is freed after cancellation completes. - id copiedHandler = nil; - @synchronized(self) { - copiedHandler = self->_handler; - self->_handler = nil; - } - - [copiedHandler didCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; - }); - } else { - _handler = nil; - } + copiedFirstInterceptor = _firstInterceptor; + } + if ([copiedFirstInterceptor respondsToSelector:@selector(cancel)]) { + dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ + [copiedFirstInterceptor cancel]; + }); } - [copiedCall cancel]; } -- (void)writeData:(NSData *)data { - GRXBufferedPipe *copiedPipe = nil; - @synchronized(self) { - NSAssert(!_canceled, @"Call already canceled."); - NSAssert(!_finished, @"Call is half-closed before sending data."); - if (_canceled) { - return; - } - if (_finished) { - return; - } - - if (_pipe) { - copiedPipe = _pipe; - } +- (void)writeData:(id)data { + id copiedFirstInterceptor; + @synchronized (self) { + copiedFirstInterceptor = _firstInterceptor; + } + if ([copiedFirstInterceptor respondsToSelector:@selector(writeData:)]) { + dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ + [copiedFirstInterceptor writeData:data]; + }); } - [copiedPipe writeValue:data]; } - (void)finish { - GRXBufferedPipe *copiedPipe = nil; - @synchronized(self) { - NSAssert(_started, @"Call not started."); - NSAssert(!_canceled, @"Call already canceled."); - NSAssert(!_finished, @"Call already half-closed."); - if (!_started) { - return; - } - if (_canceled) { - return; - } - if (_finished) { - return; - } - - if (_pipe) { - copiedPipe = _pipe; - _pipe = nil; - } - _finished = YES; + id copiedFirstInterceptor; + @synchronized (self) { + copiedFirstInterceptor = _firstInterceptor; } - [copiedPipe writesFinishedWithError:nil]; -} - -- (void)issueInitialMetadata:(NSDictionary *)initialMetadata { - @synchronized(self) { - if (initialMetadata != nil && - [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { - dispatch_async(_dispatchQueue, ^{ - id copiedHandler = nil; - @synchronized(self) { - copiedHandler = self->_handler; - } - [copiedHandler didReceiveInitialMetadata:initialMetadata]; - }); - } + if ([copiedFirstInterceptor respondsToSelector:@selector(finish)]) { + dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ + [copiedFirstInterceptor finish]; + }); } } -- (void)issueMessage:(id)message { - @synchronized(self) { - if (message != nil && [_handler respondsToSelector:@selector(didReceiveRawMessage:)]) { - dispatch_async(_dispatchQueue, ^{ - id copiedHandler = nil; - @synchronized(self) { - copiedHandler = self->_handler; - } - [copiedHandler didReceiveRawMessage:message]; - }); - } +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + id copiedFirstInterceptor; + @synchronized (self) { + copiedFirstInterceptor = _firstInterceptor; } -} - -- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - @synchronized(self) { - if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { - dispatch_async(_dispatchQueue, ^{ - id copiedHandler = nil; - @synchronized(self) { - copiedHandler = self->_handler; - // Clean up _handler so that no more responses are reported to the handler. - self->_handler = nil; - } - [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; - }); - } else { - _handler = nil; - } + if ([copiedFirstInterceptor respondsToSelector:@selector(receiveNextMessages:)]) { + dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ + [copiedFirstInterceptor receiveNextMessages:numberOfMessages]; + }); } } @@ -427,6 +297,15 @@ const char *kCFStreamVarName = "grpc_cfstream"; // The OAuth2 token fetched from a token provider. NSString *_fetchedOauth2AccessToken; + + // The callback to be called when a write message op is done. + void (^_writeDone)(void); + + // Indicate a read request to core is pending. + BOOL _pendingCoreRead; + + // Indicate pending read message request from user. + NSUInteger _pendingReceiveNextMessages; } @synthesize state = _state; @@ -486,12 +365,26 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (instancetype)initWithHost:(NSString *)host path:(NSString *)path callSafety:(GRPCCallSafety)safety - requestsWriter:(GRXWriter *)requestWriter + requestsWriter:(GRXWriter *)requestsWriter callOptions:(GRPCCallOptions *)callOptions { + return [self initWithHost:host + path:path + callSafety:safety + requestsWriter:requestsWriter + callOptions:callOptions + writeDone:nil]; +} + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone { // Purposely using pointer rather than length (host.length == 0) for backwards compatibility. NSAssert(host != nil && path != nil, @"Neither host nor path can be nil."); NSAssert(safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); - NSAssert(requestWriter.state == GRXWriterStateNotStarted, + NSAssert(requestsWriter.state == GRXWriterStateNotStarted, @"The requests writer can't be already started."); if (!host || !path) { return nil; @@ -499,7 +392,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; if (safety > GRPCCallSafetyCacheableRequest) { return nil; } - if (requestWriter.state != GRXWriterStateNotStarted) { + if (requestsWriter.state != GRXWriterStateNotStarted) { return nil; } @@ -512,16 +405,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Serial queue to invoke the non-reentrant methods of the grpc_call object. _callQueue = dispatch_queue_create("io.grpc.call", DISPATCH_QUEUE_SERIAL); - _requestWriter = requestWriter; - + _requestWriter = requestsWriter; _requestHeaders = [[GRPCRequestHeaders alloc] initWithCall:self]; + _writeDone = writeDone; - if ([requestWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { + if ([requestsWriter isKindOfClass:[GRXImmediateSingleWriter class]]) { _unaryCall = YES; _unaryOpBatch = [NSMutableArray arrayWithCapacity:kMaxClientBatch]; } _responseQueue = dispatch_get_main_queue(); + + // do not start a read until initial metadata is received + _pendingReceiveNextMessages = 0; + _pendingCoreRead = YES; } return self; } @@ -593,11 +490,16 @@ const char *kCFStreamVarName = "grpc_cfstream"; // If the call is currently paused, this is a noop. Restarting the call will invoke this // method. // TODO(jcanizales): Rename to readResponseIfNotPaused. -- (void)startNextRead { +- (void)maybeStartNextRead { @synchronized(self) { if (_state != GRXWriterStateStarted) { return; } + if (_callOptions.flowControlEnabled && (_pendingCoreRead || _pendingReceiveNextMessages == 0)) { + return; + } + _pendingCoreRead = YES; + _pendingReceiveNextMessages--; } dispatch_async(_callQueue, ^{ @@ -620,6 +522,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. @synchronized(strongSelf) { + strongSelf->_pendingCoreRead = NO; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeResourceExhausted @@ -635,7 +538,13 @@ const char *kCFStreamVarName = "grpc_cfstream"; @synchronized(strongSelf) { [strongSelf->_responseWriteable enqueueValue:data completionHandler:^{ - [strongSelf startNextRead]; + __strong GRPCCall *strongSelf = weakSelf; + if (strongSelf) { + @synchronized(strongSelf) { + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } + } }]; } } @@ -686,6 +595,20 @@ const char *kCFStreamVarName = "grpc_cfstream"; }); } +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + if (numberOfMessages == 0) { + return; + } + @synchronized(self) { + _pendingReceiveNextMessages += numberOfMessages; + + if (_state != GRXWriterStateStarted || !_callOptions.flowControlEnabled) { + return; + } + [self maybeStartNextRead]; + } +} + #pragma mark GRXWriteable implementation // Only called from the call queue. The error handler will be called from the @@ -699,9 +622,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf->_requestWriter.state = GRXWriterStateStarted; + if (strongSelf->_writeDone) { + strongSelf->_writeDone(); + } } }; - GRPCOpSendMessage *op = [[GRPCOpSendMessage alloc] initWithMessage:message handler:resumingHandler]; if (!_unaryCall) { @@ -778,8 +703,11 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Response headers received. __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; + @synchronized(strongSelf) { + strongSelf.responseHeaders = headers; + strongSelf->_pendingCoreRead = NO; + [strongSelf maybeStartNextRead]; + } } } completionHandler:^(NSError *error, NSDictionary *trailers) { @@ -933,7 +861,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; case GRXWriterStateStarted: if (_state == GRXWriterStatePaused) { _state = newState; - [self startNextRead]; + [self maybeStartNextRead]; } return; case GRXWriterStateNotStarted: diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b5bf4c9eb6c..6f985c8d952 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -90,6 +90,23 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(readonly) NSTimeInterval timeout; +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call issues a didReceiveMessage + * callback. + */ +@property(readonly) BOOL flowControlEnabled; + +/** + * An array of interceptor factories. When a call starts, interceptors are created + * by these factories and chained together with the same order as the factories in + * this array. This parameter should not be modified by any interceptor and will + * not take effect if done so. + */ +@property(copy, readonly) NSArray *interceptorFactories; + + // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** @@ -232,6 +249,28 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(readwrite) NSTimeInterval timeout; +/** + * Enable flow control of a gRPC call. The option is default to NO. If set to YES, writeData: method + * should only be called at most once before a didWriteData callback is issued, and + * receiveNextMessage: must be called each time before gRPC call can issue a didReceiveMessage + * callback. + * + * If writeData: method is called more than once before issuance of a didWriteData callback, gRPC + * will continue to queue the message and write them to gRPC core in order. However, the user + * assumes their own responsibility of flow control by keeping tracking of the pending writes in + * the call. + */ +@property(readwrite) BOOL flowControlEnabled; + +/** + * An array of interceptor factories. When a call starts, interceptors are created + * by these factories and chained together with the same order as the factories in + * this array. This parameter should not be modified by any interceptor and will + * not take effect if done so. + */ +@property(copy, readwrite) NSArray *interceptorFactories; + + // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index e59a812bd85..5a270407620 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -22,6 +22,8 @@ // The default values for the call options. static NSString *const kDefaultServerAuthority = nil; static const NSTimeInterval kDefaultTimeout = 0; +static const BOOL kDefaultFlowControlEnabled = NO; +static NSArray *const kDefaultInterceptorFactories = nil; static NSDictionary *const kDefaultInitialMetadata = nil; static NSString *const kDefaultUserAgentPrefix = nil; static const NSUInteger kDefaultResponseSizeLimit = 0; @@ -59,6 +61,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @protected NSString *_serverAuthority; NSTimeInterval _timeout; + BOOL _flowControlEnabled; + NSArray *_interceptorFactories; NSString *_oauth2AccessToken; id _authTokenProvider; NSDictionary *_initialMetadata; @@ -84,6 +88,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @synthesize serverAuthority = _serverAuthority; @synthesize timeout = _timeout; +@synthesize flowControlEnabled = _flowControlEnabled; +@synthesize interceptorFactories = _interceptorFactories; @synthesize oauth2AccessToken = _oauth2AccessToken; @synthesize authTokenProvider = _authTokenProvider; @synthesize initialMetadata = _initialMetadata; @@ -109,6 +115,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout + flowControlEnabled:kDefaultFlowControlEnabled + interceptorFactories:kDefaultInterceptorFactories oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider initialMetadata:kDefaultInitialMetadata @@ -134,6 +142,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)initWithServerAuthority:(NSString *)serverAuthority timeout:(NSTimeInterval)timeout + flowControlEnabled:(BOOL)flowControlEnabled + interceptorFactories:(NSArray *)interceptorFactories oauth2AccessToken:(NSString *)oauth2AccessToken authTokenProvider:(id)authTokenProvider initialMetadata:(NSDictionary *)initialMetadata @@ -158,6 +168,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { if ((self = [super init])) { _serverAuthority = [serverAuthority copy]; _timeout = timeout < 0 ? 0 : timeout; + _flowControlEnabled = flowControlEnabled; + _interceptorFactories = interceptorFactories; _oauth2AccessToken = [oauth2AccessToken copy]; _authTokenProvider = authTokenProvider; _initialMetadata = @@ -193,6 +205,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + flowControlEnabled:_flowControlEnabled + interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -221,6 +235,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:[_serverAuthority copy] timeout:_timeout + flowControlEnabled:_flowControlEnabled + interceptorFactories:_interceptorFactories oauth2AccessToken:[_oauth2AccessToken copy] authTokenProvider:_authTokenProvider initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata @@ -301,6 +317,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { @dynamic serverAuthority; @dynamic timeout; +@dynamic flowControlEnabled; +@dynamic interceptorFactories; @dynamic oauth2AccessToken; @dynamic authTokenProvider; @dynamic initialMetadata; @@ -326,6 +344,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout + flowControlEnabled:kDefaultFlowControlEnabled + interceptorFactories:kDefaultInterceptorFactories oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider initialMetadata:kDefaultInitialMetadata @@ -353,6 +373,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + flowControlEnabled:_flowControlEnabled + interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -381,6 +403,8 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout + flowControlEnabled:_flowControlEnabled + interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider initialMetadata:_initialMetadata @@ -417,6 +441,14 @@ static BOOL areObjectsEqual(id obj1, id obj2) { } } +- (void)setFlowControlEnabled:(BOOL)flowControlEnabled { + _flowControlEnabled = flowControlEnabled; +} + +- (void)setInterceptorFactories:(NSArray *)interceptorFactories { + _interceptorFactories = interceptorFactories; +} + - (void)setOauth2AccessToken:(NSString *)oauth2AccessToken { _oauth2AccessToken = [oauth2AccessToken copy]; } diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h new file mode 100644 index 00000000000..4ec71f9c271 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -0,0 +1,152 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * API for interceptors implementation. This feature is currently EXPERIMENTAL and is subject to + * breaking changes without prior notice. + */ + +#import "GRPCCall.h" + +NS_ASSUME_NONNULL_BEGIN + +@class GRPCInterceptorManager; +@class GRPCInterceptor; + +@protocol GRPCInterceptorInterface + +/** The queue on which all methods of this interceptor should be dispatched on */ +@property(readonly) dispatch_queue_t requestDispatchQueue; + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions; + +- (void)writeData:(id)data; + +- (void)finish; + +- (void)cancel; + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +@end + +@protocol GRPCInterceptorFactory + +/** + * Create an interceptor object. gRPC uses the returned object as the interceptor for the current + * call + */ +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; + +@end + +@interface GRPCInterceptorManager : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +- (nullable instancetype)initWithNextInerceptor:(id)nextInterceptor NS_DESIGNATED_INITIALIZER; + +/** Set the previous interceptor in the chain. Can only be set once. */ +- (void)setPreviousInterceptor:(id)previousInterceptor; + +/** Indicate shutdown of the interceptor; release the reference to other interceptors */ +- (void)shutDown; + +// Methods to forward GRPCInterceptorInterface calls to the next interceptor + +/** Notify the next interceptor in the chain to start the call and pass arguments */ +- (void)startNextInterceptorWithRequest:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions; + +/** Pass a message to be sent to the next interceptor in the chain */ +- (void)writeNextInterceptorWithData:(id)data; + +/** Notify the next interceptor in the chain to finish the call */ +- (void)finishNextInterceptor; + +/** Notify the next interceptor in the chain to cancel the call */ +- (void)cancelNextInterceptor; + +/** Notify the next interceptor in the chain to receive more messages */ +- (void)receiveNextInterceptorMessages:(NSUInteger)numberOfMessages; + +// Methods to forward GRPCResponseHandler callbacks to the previous object + +/** Forward initial metadata to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorWithInitialMetadata:(nullable NSDictionary *)initialMetadata; + +/** Forward a received message to the previous interceptor in the chain */ +- (void)forwardPreviousIntercetporWithData:(nullable id)data; + +/** Forward call close and trailing metadata to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorCloseWithTrailingMetadata: +(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; + +/** Forward write completion to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorDidWriteData; + +@end + +/** + * Base class for a gRPC interceptor. The implementation of the base class provides default behavior + * of an interceptor, which is simply forward a request/callback to the next/previous interceptor in + * the chain. The base class implementation uses the same dispatch queue for both requests and + * callbacks. + * + * An interceptor implementation should inherit from this base class and initialize the base class + * with [super initWithInterceptorManager:dispatchQueue:] for the default implementation to function + * properly. + */ +@interface GRPCInterceptor : NSObject + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +/** + * Initialize the interceptor with the next interceptor in the chain, and provide the dispatch queue + * that this interceptor's methods are dispatched onto. + */ +- (nullable instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + requestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue NS_DESIGNATED_INITIALIZER; + +// Default implementation of GRPCInterceptorInterface + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions; +- (void)writeData:(id)data; +- (void)finish; +- (void)cancel; +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +// Default implementation of GRPCResponeHandler + +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveData:(id)data; +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; +- (void)didWriteData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.m b/src/objective-c/GRPCClient/GRPCInterceptor.m new file mode 100644 index 00000000000..ac0b69f14eb --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCInterceptor.m @@ -0,0 +1,222 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#import "GRPCInterceptor.h" + +@implementation GRPCInterceptorManager { + id _nextInterceptor; + id _previousInterceptor; +} + +- (instancetype)initWithNextInerceptor:(id)nextInterceptor { + if ((self = [super init])) { + _nextInterceptor = nextInterceptor; + } + + return self; +} + +- (void)setPreviousInterceptor:(id)previousInterceptor { + _previousInterceptor = previousInterceptor; +} + +- (void)shutDown { + _nextInterceptor = nil; + _previousInterceptor = nil; +} + +- (void)startNextInterceptorWithRequest:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions { + if ([_nextInterceptor respondsToSelector:@selector(startWithRequestOptions:callOptions:)]) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor startWithRequestOptions:requestOptions + callOptions:callOptions]; + }); + } +} + +- (void)writeNextInterceptorWithData:(id)data { + if ([_nextInterceptor respondsToSelector:@selector(writeData:)]) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor writeData:data]; + }); + } +} + +- (void)finishNextInterceptor { + if ([_nextInterceptor respondsToSelector:@selector(finish)]) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor finish]; + }); + } +} + +- (void)cancelNextInterceptor { + if ([_nextInterceptor respondsToSelector:@selector(cancel)]) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor cancel]; + }); + } +} + +/** Notify the next interceptor in the chain to receive more messages */ +- (void)receiveNextInterceptorMessages:(NSUInteger)numberOfMessages { + if ([_nextInterceptor respondsToSelector:@selector(receiveNextMessages:)]) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor receiveNextMessages:numberOfMessages]; + }); + } +} + +// Methods to forward GRPCResponseHandler callbacks to the previous object + +/** Forward initial metadata to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorWithInitialMetadata:(nullable NSDictionary *)initialMetadata { + if ([_previousInterceptor respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + id copiedPreviousInterceptor = _previousInterceptor; + dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ + [copiedPreviousInterceptor didReceiveInitialMetadata:initialMetadata]; + }); + } +} + +/** Forward a received message to the previous interceptor in the chain */ +- (void)forwardPreviousIntercetporWithData:(id)data { + if ([_previousInterceptor respondsToSelector:@selector(didReceiveData:)]) { + id copiedPreviousInterceptor = _previousInterceptor; + dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ + [copiedPreviousInterceptor didReceiveData:data]; + }); + } +} + +/** Forward call close and trailing metadata to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorCloseWithTrailingMetadata: +(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error { + if ([_previousInterceptor respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + id copiedPreviousInterceptor = _previousInterceptor; + dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ + [copiedPreviousInterceptor didCloseWithTrailingMetadata:trailingMetadata + error:error]; + }); + } +} + +/** Forward write completion to the previous interceptor in the chain */ +- (void)forwardPreviousInterceptorDidWriteData { + if ([_previousInterceptor respondsToSelector:@selector(didWriteData)]) { + id copiedPreviousInterceptor = _previousInterceptor; + dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ + [copiedPreviousInterceptor didWriteData]; + }); + } +} + +@end + +@implementation GRPCInterceptor { + GRPCInterceptorManager *_manager; + dispatch_queue_t _requestDispatchQueue; + dispatch_queue_t _responseDispatchQueue; +} + +- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + requestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue { + if ((self = [super init])) { + _manager = interceptorManager; + _requestDispatchQueue = requestDispatchQueue; + _responseDispatchQueue = responseDispatchQueue; + } + + return self; +} + +- (dispatch_queue_t)requestDispatchQueue { + return _requestDispatchQueue; +} + +- (dispatch_queue_t)dispatchQueue { + return _responseDispatchQueue; +} + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions { + [_manager startNextInterceptorWithRequest:requestOptions + callOptions:callOptions]; +} + +- (void)writeData:(id)data { + [_manager writeNextInterceptorWithData:data]; +} + +- (void)finish { + [_manager finishNextInterceptor]; +} + +- (void)cancel { + [_manager cancelNextInterceptor]; + [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled" + }]]; + [_manager shutDown]; +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + [_manager receiveNextInterceptorMessages:numberOfMessages]; +} + + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + [_manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; +} + +- (void)didReceiveRawMessage:(id)message { + NSAssert(NO, @"The method didReceiveRawMessage is deprecated and cannot be used with interceptor"); + NSLog(@"The method didReceiveRawMessage is deprecated and cannot be used with interceptor"); + abort(); +} + +- (void)didReceiveData:(id)data { + [_manager forwardPreviousIntercetporWithData:data]; +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(NSError *)error { + [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata + error:error]; + [_manager shutDown]; +} + +- (void)didWriteData { + [_manager forwardPreviousInterceptorDidWriteData]; +} + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCCall+V2API.h b/src/objective-c/GRPCClient/private/GRPCCall+V2API.h new file mode 100644 index 00000000000..34871ad5c2a --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCall+V2API.h @@ -0,0 +1,18 @@ +@interface GRPCCall (V2API) + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions; + +- (instancetype)initWithHost:(NSString *)host + path:(NSString *)path + callSafety:(GRPCCallSafety)safety + requestsWriter:(GRXWriter *)requestsWriter + callOptions:(GRPCCallOptions *)callOptions + writeDone:(void (^)(void))writeDone; + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +@end diff --git a/src/objective-c/GRPCClient/private/GRPCCallInternal.h b/src/objective-c/GRPCClient/private/GRPCCallInternal.h new file mode 100644 index 00000000000..28bc1e46aff --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCallInternal.h @@ -0,0 +1,25 @@ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GRPCCall2Internal : NSObject + +- (instancetype)init; + +- (void)setResponseHandler:(id)responseHandler; + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(nullable GRPCCallOptions *)callOptions; + +- (void)writeData:(NSData *)data; + +- (void)finish; + +- (void)cancel; + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/GRPCClient/private/GRPCCallInternal.m b/src/objective-c/GRPCClient/private/GRPCCallInternal.m new file mode 100644 index 00000000000..06912cc7fa9 --- /dev/null +++ b/src/objective-c/GRPCClient/private/GRPCCallInternal.m @@ -0,0 +1,324 @@ +#import "GRPCCallInternal.h" + +#import +#import + +#import "GRPCCall+V2API.h" + +@implementation GRPCCall2Internal { + /** Request for the call. */ + GRPCRequestOptions *_requestOptions; + /** Options for the call. */ + GRPCCallOptions *_callOptions; + /** The handler of responses. */ + id _handler; + + /** + * Make use of legacy GRPCCall to make calls. Nullified when call is finished. + */ + GRPCCall *_call; + /** Flags whether initial metadata has been published to response handler. */ + BOOL _initialMetadataPublished; + /** Streaming call writeable to the underlying call. */ + GRXBufferedPipe *_pipe; + /** Serial dispatch queue for tasks inside the call. */ + dispatch_queue_t _dispatchQueue; + /** Flags whether call has started. */ + BOOL _started; + /** Flags whether call has been canceled. */ + BOOL _canceled; + /** Flags whether call has been finished. */ + BOOL _finished; + /** The number of pending messages receiving requests. */ + NSUInteger _pendingReceiveNextMessages; +} + +- (instancetype)init { + if ((self = [super init])) { + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 + if (@available(iOS 8.0, macOS 10.10, *)) { + _dispatchQueue = dispatch_queue_create( + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + } else { +#else + { +#endif + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + } + _pipe = [GRXBufferedPipe pipe]; + } + return self; +} + +- (void)setResponseHandler:(id)responseHandler { + @synchronized (self) { + NSAssert(!_started, @"Call already started."); + if (_started) { + return; + } + _handler = responseHandler; + _initialMetadataPublished = NO; + _started = NO; + _canceled = NO; + _finished = NO; + } +} + +- (dispatch_queue_t)requestDispatchQueue { + return _dispatchQueue; +} + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions { + NSAssert(requestOptions.host.length != 0 && requestOptions.path.length != 0, + @"Neither host nor path can be nil."); + NSAssert(requestOptions.safety <= GRPCCallSafetyCacheableRequest, @"Invalid call safety value."); + if (requestOptions.host.length == 0 || requestOptions.path.length == 0) { + NSLog(@"Invalid host and path."); + return; + } + if (requestOptions.safety > GRPCCallSafetyCacheableRequest) { + NSLog(@"Invalid call safety."); + return; + } + + @synchronized (self) { + NSAssert(_handler != nil, @"Response handler required."); + if (_handler == nil) { + NSLog(@"Invalid response handler."); + return; + } + _requestOptions = requestOptions; + if (callOptions == nil) { + _callOptions = [[GRPCCallOptions alloc] init]; + } else { + _callOptions = [callOptions copy]; + } + } + + [self start]; +} + +- (void)start { + GRPCCall *copiedCall = nil; + @synchronized(self) { + NSAssert(!_started, @"Call already started."); + NSAssert(!_canceled, @"Call already canceled."); + if (_started) { + return; + } + if (_canceled) { + return; + } + + _started = YES; + + _call = [[GRPCCall alloc] initWithHost:_requestOptions.host + path:_requestOptions.path + callSafety:_requestOptions.safety + requestsWriter:_pipe + callOptions:_callOptions + writeDone:^{ + @synchronized(self) { + if (self->_handler) { + [self issueDidWriteData]; + } + } + }]; + [_call setResponseDispatchQueue:_dispatchQueue]; + if (_callOptions.initialMetadata) { + [_call.requestHeaders addEntriesFromDictionary:_callOptions.initialMetadata]; + } + if (_pendingReceiveNextMessages > 0) { + [_call receiveNextMessages:_pendingReceiveNextMessages]; + _pendingReceiveNextMessages = 0; + } + copiedCall = _call; + } + + void (^valueHandler)(id value) = ^(id value) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + if (value) { + [self issueMessage:value]; + } + } + } + }; + void (^completionHandler)(NSError *errorOrNil) = ^(NSError *errorOrNil) { + @synchronized(self) { + if (self->_handler) { + if (!self->_initialMetadataPublished) { + self->_initialMetadataPublished = YES; + [self issueInitialMetadata:self->_call.responseHeaders]; + } + [self issueClosedWithTrailingMetadata:self->_call.responseTrailers error:errorOrNil]; + } + // Clearing _call must happen *after* dispatching close in order to get trailing + // metadata from _call. + if (self->_call) { + // Clean up the request writers. This should have no effect to _call since its + // response writeable is already nullified. + [self->_pipe writesFinishedWithError:nil]; + self->_call = nil; + self->_pipe = nil; + } + } + }; + id responseWriteable = + [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; + [copiedCall startWithWriteable:responseWriteable]; +} + +- (void)cancel { + GRPCCall *copiedCall = nil; + @synchronized(self) { + if (_canceled) { + return; + } + + _canceled = YES; + + copiedCall = _call; + _call = nil; + _pipe = nil; + + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + id copiedHandler = _handler; + _handler = nil; + dispatch_async(copiedHandler.dispatchQueue, ^{ + [copiedHandler didCloseWithTrailingMetadata:nil + error:[NSError errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; + }); + } else { + _handler = nil; + } + } + [copiedCall cancel]; +} + +- (void)writeData:(id)data { + GRXBufferedPipe *copiedPipe = nil; + @synchronized(self) { + NSAssert(!_canceled, @"Call already canceled."); + NSAssert(!_finished, @"Call is half-closed before sending data."); + if (_canceled) { + return; + } + if (_finished) { + return; + } + + if (_pipe) { + copiedPipe = _pipe; + } + } + [copiedPipe writeValue:data]; +} + +- (void)finish { + GRXBufferedPipe *copiedPipe = nil; + @synchronized(self) { + NSAssert(_started, @"Call not started."); + NSAssert(!_canceled, @"Call already canceled."); + NSAssert(!_finished, @"Call already half-closed."); + if (!_started) { + return; + } + if (_canceled) { + return; + } + if (_finished) { + return; + } + + if (_pipe) { + copiedPipe = _pipe; + _pipe = nil; + } + _finished = YES; + } + [copiedPipe writesFinishedWithError:nil]; +} + +- (void)issueInitialMetadata:(NSDictionary *)initialMetadata { + @synchronized(self) { + if (initialMetadata != nil && + [_handler respondsToSelector:@selector(didReceiveInitialMetadata:)]) { + id copiedHandler = _handler; + dispatch_async(_handler.dispatchQueue, ^{ + [copiedHandler didReceiveInitialMetadata:initialMetadata]; + }); + } + } +} + +- (void)issueMessage:(id)message { + @synchronized(self) { + if (message != nil) { + if ([_handler respondsToSelector:@selector(didReceiveData:)]) { + id copiedHandler = _handler; + dispatch_async(_handler.dispatchQueue, ^{ + [copiedHandler didReceiveData:message]; + }); + } else if ([_handler respondsToSelector:@selector(didReceiveRawMessage:)]) { + id copiedHandler = _handler; + dispatch_async(_handler.dispatchQueue, ^{ + [copiedHandler didReceiveRawMessage:message]; + }); + } + } + } +} + +- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { + id copiedHandler = _handler; + // Clean up _handler so that no more responses are reported to the handler. + _handler = nil; + dispatch_async(copiedHandler.dispatchQueue, ^{ + [copiedHandler didCloseWithTrailingMetadata:trailingMetadata error:error]; + }); + } else { + _handler = nil; + } + } +} + +- (void)issueDidWriteData { + @synchronized(self) { + if (_callOptions.flowControlEnabled && [_handler respondsToSelector:@selector(didWriteData)]) { + id copiedHandler = _handler; + dispatch_async(copiedHandler.dispatchQueue, ^{ + [copiedHandler didWriteData]; + }); + } + } +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + // branching based on _callOptions.flowControlEnabled is handled inside _call + GRPCCall *copiedCall = nil; + @synchronized(self) { + copiedCall = _call; + if (copiedCall == nil) { + _pendingReceiveNextMessages += numberOfMessages; + return; + } + } + [copiedCall receiveNextMessages:numberOfMessages]; +} + +@end diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h index 8ce3421cc17..12db46adeda 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.h +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -57,6 +57,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; +/** + * Issued when flow control is enabled for the call and a message (written with writeMessage: method + * of GRPCStreamingProtoCall or the initializer of GRPCUnaryProtoCall) is passed to gRPC core with + * SEND_MESSAGE operation. + */ +- (void)didWriteMessage; + @end /** A unary-request RPC call with Protobuf. */ @@ -130,6 +137,26 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)finish; +/** + * Tell gRPC to receive another message. + * + * This method should only be used when flow control is enabled. If flow control is enabled, gRPC + * will only receive additional messages after the user indicates so by using either + * receiveNextMessage: or receiveNextMessages: methods. If flow control is not enabled, messages + * will be automatically received after the previous one is delivered. + */ +- (void)receiveNextMessage; + +/** + * Tell gRPC to receive another N message. + * + * This method should only be used when flow control is enabled. If flow control is enabled, the + * messages received from the server are buffered in gRPC until the user want to receive the next + * message. If flow control is not enabled, messages will be automatically received after the + * previous one is delivered. + */ +- (void)receiveNextMessages:(NSUInteger)numberOfMessages; + @end NS_ASSUME_NONNULL_END diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index 0ab96a5ba2b..4700fdd1124 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -72,6 +72,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing - (void)start { [_call start]; + [_call receiveNextMessage]; [_call writeMessage:_message]; [_call finish]; } @@ -197,6 +198,17 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing [copiedCall finish]; } +- (void)receiveNextMessage { + [self receiveNextMessages:1]; +} +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + GRPCCall2 *copiedCall; + @synchronized(self) { + copiedCall = _call; + } + [copiedCall receiveNextMessages:numberOfMessages]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { @synchronized(self) { if (initialMetadata != nil && @@ -212,11 +224,11 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } -- (void)didReceiveRawMessage:(NSData *)message { - if (message == nil) return; +- (void)didReceiveData:(id)data { + if (data == nil) return; NSError *error = nil; - GPBMessage *parsed = [_responseClass parseFromData:message error:&error]; + GPBMessage *parsed = [_responseClass parseFromData:data error:&error]; @synchronized(self) { if (parsed && [_handler respondsToSelector:@selector(didReceiveProtoMessage:)]) { dispatch_async(_dispatchQueue, ^{ @@ -236,7 +248,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } [copiedHandler didCloseWithTrailingMetadata:nil - error:ErrorForBadProto(message, self->_responseClass, error)]; + error:ErrorForBadProto(data, self->_responseClass, error)]; }); [_call cancel]; _call = nil; @@ -260,6 +272,20 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing } } +- (void)didWriteData { + @synchronized(self) { + if ([_handler respondsToSelector:@selector(didWriteMessage)]) { + dispatch_async(_dispatchQueue, ^{ + id copiedHandler = nil; + @synchronized(self) { + copiedHandler = self->_handler; + } + [copiedHandler didWriteMessage]; + }); + } + } +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index ea777e27812..db293750ca3 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -40,11 +40,13 @@ static NSString *const kService = @"TestService"; static GRPCProtoMethod *kInexistentMethod; static GRPCProtoMethod *kEmptyCallMethod; static GRPCProtoMethod *kUnaryCallMethod; +static GRPCProtoMethod *kOutputStreamingCallMethod; static GRPCProtoMethod *kFullDuplexCallMethod; static const int kSimpleDataLength = 100; -static const NSTimeInterval kTestTimeout = 16; +static const NSTimeInterval kTestTimeout = 8; +static const NSTimeInterval kInvertedTimeout = 2; // Reveal the _class ivar for testing access @interface GRPCCall2 () { @@ -57,6 +59,11 @@ static const NSTimeInterval kTestTimeout = 16; // Convenience class to use blocks as callbacks @interface ClientTestsBlockCallbacks : NSObject +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback; + - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; @@ -67,21 +74,33 @@ static const NSTimeInterval kTestTimeout = 16; void (^_initialMetadataCallback)(NSDictionary *); void (^_messageCallback)(id); void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeDataCallback)(void); dispatch_queue_t _dispatchQueue; } - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeDataCallback:(void (^)(void))writeDataCallback { if ((self = [super init])) { _initialMetadataCallback = initialMetadataCallback; _messageCallback = messageCallback; _closeCallback = closeCallback; + _writeDataCallback = writeDataCallback; _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } return self; } +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeDataCallback:nil]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (self->_initialMetadataCallback) { self->_initialMetadataCallback(initialMetadata); @@ -100,6 +119,12 @@ static const NSTimeInterval kTestTimeout = 16; } } +- (void)didWriteData { + if (self->_writeDataCallback) { + self->_writeDataCallback(); + } +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } @@ -120,6 +145,9 @@ static const NSTimeInterval kTestTimeout = 16; [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"EmptyCall"]; kUnaryCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"]; + kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage + service:kService + method:@"StreamingOutputCall"]; kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; } @@ -478,4 +506,268 @@ static const NSTimeInterval kTestTimeout = 16; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } +- (void)testFlowControlWrite { + __weak XCTestExpectation *expectWriteData = + [self expectationWithDescription:@"Reported write data"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + GRPCCall2 *call = + [[GRPCCall2 alloc] initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:nil + writeDataCallback:^{ + [expectWriteData fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessages:1]; + [call writeData:[request data]]; + + // Wait for 3 seconds and make sure we do not receive the response + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; + + [call finish]; +} + +- (void)testFlowControlRead { + __weak __block XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message not delivered without recvNextMessage"]; + __weak __block XCTestExpectation *expectPassedMessage = nil; + __weak __block XCTestExpectation *expectBlockedClose = + [self expectationWithDescription:@"Call not closed with pending message"]; + __weak __block XCTestExpectation *expectPassedClose = nil; + expectBlockedMessage.inverted = YES; + expectBlockedClose.inverted = YES; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block int unblocked = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (!unblocked) { + [expectBlockedMessage fulfill]; + } else { + [expectPassedMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + if (!unblocked) { + [expectBlockedClose fulfill]; + } else { + [expectPassedClose fulfill]; + } + }] + callOptions:options]; + + [call start]; + [call writeData:[request data]]; + [call finish]; + + // Wait to make sure we do not receive the response + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; + + expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + expectPassedClose = [self expectationWithDescription:@"Close delivered after receiveNextMessage"]; + + unblocked = YES; + [call receiveNextMessages:1]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testFlowControlMultipleMessages { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"two messages delivered with receiveNextMessage"]; + expectPassedMessage.expectedFulfillmentCount = 2; + __weak XCTestExpectation *expectBlockedMessage = + [self expectationWithDescription:@"Message 3 not delivered"]; + expectBlockedMessage.inverted = YES; + __weak XCTestExpectation *expectWriteTwice = + [self expectationWithDescription:@"Write 2 messages done"]; + expectWriteTwice.expectedFulfillmentCount = 2; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block NSUInteger messageId = 0; + __block GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + if (messageId <= 1) { + [expectPassedMessage fulfill]; + } else { + [expectBlockedMessage fulfill]; + } + messageId++; + } + closeCallback:nil + writeDataCallback:^{ + [expectWriteTwice fulfill]; + }] + callOptions:options]; + + [call receiveNextMessages:2]; + [call start]; + [call writeData:[request data]]; + [call writeData:[request data]]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testFlowControlReadReadyBeforeStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = kSimpleDataLength; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectPassedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:^(NSDictionary *ttrailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] + callOptions:options]; + + [call receiveNextMessages:1]; + [call start]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kInvertedTimeout handler:nil]; +} + +- (void)testFlowControlReadReadyAfterStart { + __weak XCTestExpectation *expectPassedMessage = + [self expectationWithDescription:@"Message delivered with receiveNextMessage"]; + __weak XCTestExpectation *expectPassedClose = + [self expectationWithDescription:@"Close delivered with receiveNextMessage"]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *callRequest = + [[GRPCRequestOptions alloc] initWithHost:(NSString *)kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + options.flowControlEnabled = YES; + __block BOOL closed = NO; + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:callRequest + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *message) { + [expectPassedMessage fulfill]; + XCTAssertFalse(closed); + } + closeCallback:^(NSDictionary *trailers, NSError *error) { + closed = YES; + [expectPassedClose fulfill]; + }] + callOptions:options]; + + [call start]; + [call receiveNextMessages:1]; + [call writeData:[request data]]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testFlowControlReadNonBlockingFailure { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.flowControlEnabled = YES; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + + RMTEchoStatus *status = [RMTEchoStatus message]; + status.code = 2; + status.message = @"test"; + request.responseStatus = status; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received unexpected message"); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, @"Expecting non-nil error"); + XCTAssertEqual(error.code, 2); + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 0d2c409f6f3..42365d2be2c 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -26,6 +26,7 @@ #import #import #import +#import #import #import #import @@ -79,6 +80,11 @@ BOOL isRemoteInteropTest(NSString *host) { // Convenience class to use blocks as callbacks @interface InteropTestsBlockCallbacks : NSObject +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback; + - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; @@ -89,21 +95,33 @@ BOOL isRemoteInteropTest(NSString *host) { void (^_initialMetadataCallback)(NSDictionary *); void (^_messageCallback)(id); void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeMessageCallback)(void); dispatch_queue_t _dispatchQueue; } - (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback { if ((self = [super init])) { _initialMetadataCallback = initialMetadataCallback; _messageCallback = messageCallback; _closeCallback = closeCallback; + _writeMessageCallback = writeMessageCallback; _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); } return self; } +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeMessageCallback:nil]; +} + - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { if (_initialMetadataCallback) { _initialMetadataCallback(initialMetadata); @@ -122,10 +140,212 @@ BOOL isRemoteInteropTest(NSString *host) { } } +- (void)didWriteMessage { + if (_writeMessageCallback) { + _writeMessageCallback(); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end + +@interface DefaultInterceptorFactory : NSObject + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; + +@end + +@implementation DefaultInterceptorFactory + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { + dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + return [[GRPCInterceptor alloc] initWithInterceptorManager:interceptorManager + requestDispatchQueue:queue + responseDispatchQueue:queue]; +} + +@end + +@interface HookInterceptorFactory : NSObject + +- (instancetype)initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; + +@end + +@interface HookIntercetpor : GRPCInterceptor + +- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + dispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; + +@end + +@implementation HookInterceptorFactory { + void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); + void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_finishHook)(GRPCInterceptorManager *manager); + void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); + void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); + void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); + void (^_didWriteDataHook)(GRPCInterceptorManager *manager); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { + if ((self = [super init])) { + _dispatchQueue = dispatchQueue; + _startHook = startHook; + _writeDataHook = writeDataHook; + _finishHook = finishHook; + _receiveNextMessagesHook = receiveNextMessagesHook; + _responseHeaderHook = responseHeaderHook; + _responseDataHook = responseDataHook; + _responseCloseHook = responseCloseHook; + _didWriteDataHook = didWriteDataHook; + _dispatchQueue = dispatchQueue; + } + return self; +} + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { + return [[HookIntercetpor alloc] initWithInterceptorManager:interceptorManager + dispatchQueue:_dispatchQueue + startHook:_startHook + writeDataHook:_writeDataHook + finishHook:_finishHook + receiveNextMessagesHook:_receiveNextMessagesHook + responseHeaderHook:_responseHeaderHook + responseDataHook:_responseDataHook + responseCloseHook:_responseCloseHook + didWriteDataHook:_didWriteDataHook]; +} + +@end + +@implementation HookIntercetpor { + void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); + void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_finishHook)(GRPCInterceptorManager *manager); + void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); + void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); + void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); + void (^_didWriteDataHook)(GRPCInterceptorManager *manager); + GRPCInterceptorManager *_manager; + dispatch_queue_t _dispatchQueue; +} + +- (dispatch_queue_t)requestDispatchQueue { + return _dispatchQueue; +} + - (dispatch_queue_t)dispatchQueue { return _dispatchQueue; } +- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + dispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { + if ((self = [super initWithInterceptorManager:interceptorManager requestDispatchQueue:dispatchQueue responseDispatchQueue:dispatchQueue])) { + _startHook = startHook; + _writeDataHook = writeDataHook; + _finishHook = finishHook; + _receiveNextMessagesHook = receiveNextMessagesHook; + _responseHeaderHook = responseHeaderHook; + _responseDataHook = responseDataHook; + _responseCloseHook = responseCloseHook; + _didWriteDataHook = didWriteDataHook; + _dispatchQueue = dispatchQueue; + _manager = interceptorManager; + } + return self; +} + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions { + if (_startHook) { + _startHook(requestOptions, callOptions, _manager); + } +} + +- (void)writeData:(NSData *)data { + if (_writeDataHook) { + _writeDataHook(data, _manager); + } +} + +- (void)finish { + if (_finishHook) { + _finishHook(_manager); + } +} + +- (void)receiveNextMessages:(NSUInteger)numberOfMessages { + if (_receiveNextMessagesHook) { + _receiveNextMessagesHook(numberOfMessages, _manager); + } +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (_responseHeaderHook) { + _responseHeaderHook(initialMetadata, _manager); + } +} + +- (void)didReceiveData:(NSData *)data { + if (_responseDataHook) { + _responseDataHook(data, _manager); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_responseCloseHook) { + _responseCloseHook(trailingMetadata, error, _manager); + } +} + +- (void)didWriteData { + if (_didWriteDataHook) { + _didWriteDataHook(_manager); + } +} + @end #pragma mark Tests @@ -702,6 +922,67 @@ BOOL isRemoteInteropTest(NSString *host) { [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testPingPongRPCWithFlowControl { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.flowControlEnabled = YES; + __block BOOL canWriteData = NO; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testEmptyStreamRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"]; @@ -972,4 +1253,298 @@ BOOL isRemoteInteropTest(NSString *host) { } #endif +- (void)testDefaultInterceptor { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *requests = @[ @27182, @8, @1828, @45904 ]; + NSArray *responses = @[ @31415, @9, @2653, @58979 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeMessage:request]; + } else { + [call finish]; + } + // DEBUG + NSLog(@"Received message"); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + // DEBUG + NSLog(@"Received close"); + }] + callOptions:options]; + [call start]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testLoggingInterceptor { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + __block NSUInteger startCount = 0; + __block NSUInteger writeDataCount = 0; + __block NSUInteger finishCount = 0; + __block NSUInteger receiveNextMessageCount = 0; + __block NSUInteger responseHeaderCount = 0; + __block NSUInteger responseDataCount = 0; + __block NSUInteger responseCloseCount = 0; + __block NSUInteger didWriteDataCount = 0; + id factory = + [[HookInterceptorFactory alloc] initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { + startCount++; + NSLog(@"Interceptor - started call, %@, %@", requestOptions, callOptions); + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; + } + writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataCount++; + NSLog(@"Interceptor - send data, %@", data); + XCTAssertNotEqual(data.length, 0); + [manager writeNextInterceptorWithData:data]; + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + NSLog(@"Interceptor - finish call"); + [manager finishNextInterceptor]; + } + receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { + receiveNextMessageCount++; + NSLog(@"Interceptor - receive next messages, %lu", (unsigned long)numberOfMessages); + [manager receiveNextInterceptorMessages:numberOfMessages]; + } + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + NSLog(@"Interceptor - received initial metadata, %@", initialMetadata); + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataCount++; + NSLog(@"Interceptor - received data, %@", data); + XCTAssertNotEqual(data.length, 0); + [manager forwardPreviousIntercetporWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { + responseCloseCount++; + NSLog(@"Interceptor - received close, %@, %@", trailingMetadata, error); + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata + error:error]; + } + didWriteDataHook:^(GRPCInterceptorManager *manager) { + didWriteDataCount++; + NSLog(@"Interceptor - received did-write-data"); + [manager forwardPreviousInterceptorDidWriteData]; + }]; + + NSArray *requests = @[ @1, @2, @3, @4 ]; + NSArray *responses = @[ @1, @2, @3, @4 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.flowControlEnabled = YES; + options.interceptorFactories = @[ factory ]; + __block BOOL canWriteData = NO; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + XCTAssertEqual(startCount, 1); + XCTAssertEqual(writeDataCount, 4); + XCTAssertEqual(finishCount, 1); + XCTAssertEqual(receiveNextMessageCount, 4); + XCTAssertEqual(responseHeaderCount, 1); + XCTAssertEqual(responseDataCount, 4); + XCTAssertEqual(responseCloseCount, 1); + XCTAssertEqual(didWriteDataCount, 4); +} + +// Chain a default interceptor and a hook interceptor which, after two writes, cancels the call +// under the hood but forward further data to the user. +- (void)testHijackingInterceptor { + NSUInteger kCancelAfterWrites = 2; + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + + NSArray *responses = @[ @1, @2, @3, @4 ]; + __block int index = 0; + + __block NSUInteger startCount = 0; + __block NSUInteger writeDataCount = 0; + __block NSUInteger finishCount = 0; + __block NSUInteger responseHeaderCount = 0; + __block NSUInteger responseDataCount = 0; + __block NSUInteger responseCloseCount = 0; + id factory = + [[HookInterceptorFactory alloc] initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { + startCount++; + [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; + } + writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataCount++; + if (index < kCancelAfterWrites) { + [manager writeNextInterceptorWithData:data]; + } else if (index == kCancelAfterWrites) { + [manager cancelNextInterceptor]; + [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; + } else { // (index > kCancelAfterWrites) + [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; + } + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + // finish must happen after the hijacking, so directly reply with a close + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:@{ @"grpc-status" : @"0" } error:nil]; + } + receiveNextMessagesHook:nil + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataCount++; + [manager forwardPreviousIntercetporWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { + responseCloseCount++; + // since we canceled the call, it should return cancel error + XCTAssertNil(trailingMetadata); + XCTAssertNotNil(error); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + } + didWriteDataHook:nil]; + + NSArray *requests = @[ @1, @2, @3, @4 ]; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init], factory ]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + XCTAssertEqual(startCount, 1); + XCTAssertEqual(writeDataCount, 4); + XCTAssertEqual(finishCount, 1); + XCTAssertEqual(responseHeaderCount, 1); + XCTAssertEqual(responseDataCount, 2); + XCTAssertEqual(responseCloseCount, 1); +} + @end From 6fccb70f0d417f2cbcafd8dad1537913999d1c0f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Apr 2019 08:50:00 -0700 Subject: [PATCH 008/676] Add caching interceptor example --- .../project.pbxproj | 421 ++++++++++++++++++ .../InterceptorSample/AppDelegate.h | 25 ++ .../InterceptorSample/AppDelegate.m | 5 + .../AppIcon.appiconset/Contents.json | 98 ++++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 ++ .../Base.lproj/Main.storyboard | 38 ++ .../InterceptorSample/CacheInterceptor.h | 90 ++++ .../InterceptorSample/CacheInterceptor.m | 303 +++++++++++++ .../InterceptorSample/Info.plist | 45 ++ .../InterceptorSample/ViewController.h | 25 ++ .../InterceptorSample/ViewController.m | 86 ++++ .../InterceptorSample/main.m | 26 ++ .../examples/InterceptorSample/Podfile | 31 ++ 14 files changed, 1224 insertions(+) create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/Contents.json create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/LaunchScreen.storyboard create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/Main.storyboard create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/Info.plist create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m create mode 100644 src/objective-c/examples/InterceptorSample/InterceptorSample/main.m create mode 100644 src/objective-c/examples/InterceptorSample/Podfile diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj b/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..e72ef6edc61 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj @@ -0,0 +1,421 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1C4854A76EEB56F8096DBDEF /* libPods-InterceptorSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CB7A7A5B91FC976FCF4637AE /* libPods-InterceptorSample.a */; }; + 5EE960FB2266768A0044A74F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE960FA2266768A0044A74F /* AppDelegate.m */; }; + 5EE960FE2266768A0044A74F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE960FD2266768A0044A74F /* ViewController.m */; }; + 5EE961012266768A0044A74F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EE960FF2266768A0044A74F /* Main.storyboard */; }; + 5EE961032266768C0044A74F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5EE961022266768C0044A74F /* Assets.xcassets */; }; + 5EE961062266768C0044A74F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EE961042266768C0044A74F /* LaunchScreen.storyboard */; }; + 5EE961092266768C0044A74F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE961082266768C0044A74F /* main.m */; }; + 5EE9611222668CF20044A74F /* CacheInterceptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE9611122668CF20044A74F /* CacheInterceptor.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 09457A264AAE5323BF50B1F8 /* Pods-InterceptorSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InterceptorSample.debug.xcconfig"; path = "Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample.debug.xcconfig"; sourceTree = ""; }; + 5EE960F62266768A0044A74F /* InterceptorSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InterceptorSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EE960FA2266768A0044A74F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5EE960FC2266768A0044A74F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 5EE960FD2266768A0044A74F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 5EE961002266768A0044A74F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5EE961022266768C0044A74F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5EE961052266768C0044A74F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5EE961072266768C0044A74F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EE961082266768C0044A74F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5EE9610F2266774C0044A74F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5EE9611022668CE20044A74F /* CacheInterceptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheInterceptor.h; sourceTree = ""; }; + 5EE9611122668CF20044A74F /* CacheInterceptor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CacheInterceptor.m; sourceTree = ""; }; + A0789280A4035D0F22F96BE6 /* Pods-InterceptorSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InterceptorSample.release.xcconfig"; path = "Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample.release.xcconfig"; sourceTree = ""; }; + CB7A7A5B91FC976FCF4637AE /* libPods-InterceptorSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InterceptorSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5EE960F32266768A0044A74F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1C4854A76EEB56F8096DBDEF /* libPods-InterceptorSample.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5EE960ED2266768A0044A74F = { + isa = PBXGroup; + children = ( + 5EE960F82266768A0044A74F /* InterceptorSample */, + 5EE960F72266768A0044A74F /* Products */, + 9D49DB75F3BEDAFDE7028B51 /* Pods */, + BD7184728351C7DDAFBA5FA2 /* Frameworks */, + ); + sourceTree = ""; + }; + 5EE960F72266768A0044A74F /* Products */ = { + isa = PBXGroup; + children = ( + 5EE960F62266768A0044A74F /* InterceptorSample.app */, + ); + name = Products; + sourceTree = ""; + }; + 5EE960F82266768A0044A74F /* InterceptorSample */ = { + isa = PBXGroup; + children = ( + 5EE960FA2266768A0044A74F /* AppDelegate.m */, + 5EE960FC2266768A0044A74F /* ViewController.h */, + 5EE960FD2266768A0044A74F /* ViewController.m */, + 5EE960FF2266768A0044A74F /* Main.storyboard */, + 5EE961022266768C0044A74F /* Assets.xcassets */, + 5EE961042266768C0044A74F /* LaunchScreen.storyboard */, + 5EE961072266768C0044A74F /* Info.plist */, + 5EE961082266768C0044A74F /* main.m */, + 5EE9610F2266774C0044A74F /* AppDelegate.h */, + 5EE9611022668CE20044A74F /* CacheInterceptor.h */, + 5EE9611122668CF20044A74F /* CacheInterceptor.m */, + ); + path = InterceptorSample; + sourceTree = ""; + }; + 9D49DB75F3BEDAFDE7028B51 /* Pods */ = { + isa = PBXGroup; + children = ( + 09457A264AAE5323BF50B1F8 /* Pods-InterceptorSample.debug.xcconfig */, + A0789280A4035D0F22F96BE6 /* Pods-InterceptorSample.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + BD7184728351C7DDAFBA5FA2 /* Frameworks */ = { + isa = PBXGroup; + children = ( + CB7A7A5B91FC976FCF4637AE /* libPods-InterceptorSample.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5EE960F52266768A0044A74F /* InterceptorSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EE9610C2266768C0044A74F /* Build configuration list for PBXNativeTarget "InterceptorSample" */; + buildPhases = ( + 7531607F028A04DAAF5E97B5 /* [CP] Check Pods Manifest.lock */, + 5EE960F22266768A0044A74F /* Sources */, + 5EE960F32266768A0044A74F /* Frameworks */, + 5EE960F42266768A0044A74F /* Resources */, + 17700C95BAEBB27F7A3D1B01 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = InterceptorSample; + productName = InterceptorSample; + productReference = 5EE960F62266768A0044A74F /* InterceptorSample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5EE960EE2266768A0044A74F /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5EE960F52266768A0044A74F = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = 5EE960F12266768A0044A74F /* Build configuration list for PBXProject "InterceptorSample" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5EE960ED2266768A0044A74F; + productRefGroup = 5EE960F72266768A0044A74F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5EE960F52266768A0044A74F /* InterceptorSample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5EE960F42266768A0044A74F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EE961062266768C0044A74F /* LaunchScreen.storyboard in Resources */, + 5EE961032266768C0044A74F /* Assets.xcassets in Resources */, + 5EE961012266768A0044A74F /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 17700C95BAEBB27F7A3D1B01 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 7531607F028A04DAAF5E97B5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InterceptorSample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5EE960F22266768A0044A74F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EE9611222668CF20044A74F /* CacheInterceptor.m in Sources */, + 5EE960FE2266768A0044A74F /* ViewController.m in Sources */, + 5EE961092266768C0044A74F /* main.m in Sources */, + 5EE960FB2266768A0044A74F /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5EE960FF2266768A0044A74F /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5EE961002266768A0044A74F /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5EE961042266768C0044A74F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5EE961052266768C0044A74F /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5EE9610A2266768C0044A74F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 5EE9610B2266768C0044A74F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5EE9610D2266768C0044A74F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 09457A264AAE5323BF50B1F8 /* Pods-InterceptorSample.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InterceptorSample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InterceptorSample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EE9610E2266768C0044A74F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A0789280A4035D0F22F96BE6 /* Pods-InterceptorSample.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = InterceptorSample/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InterceptorSample; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5EE960F12266768A0044A74F /* Build configuration list for PBXProject "InterceptorSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EE9610A2266768C0044A74F /* Debug */, + 5EE9610B2266768C0044A74F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EE9610C2266768C0044A74F /* Build configuration list for PBXNativeTarget "InterceptorSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EE9610D2266768C0044A74F /* Debug */, + 5EE9610E2266768C0044A74F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5EE960EE2266768A0044A74F /* Project object */; +} diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h new file mode 100644 index 00000000000..c4e433787e6 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m new file mode 100644 index 00000000000..1b9f2c85dac --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m @@ -0,0 +1,5 @@ +#import "AppDelegate.h" + +@implementation AppDelegate + +@end diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/AppIcon.appiconset/Contents.json b/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..d8db8d65fd7 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/Contents.json b/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/Contents.json new file mode 100644 index 00000000000..da4a164c918 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/LaunchScreen.storyboard b/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000000..bfa36129419 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/Main.storyboard b/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..9310a8e812f --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/Base.lproj/Main.storyboard @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h new file mode 100644 index 00000000000..a2c9d668c14 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h @@ -0,0 +1,90 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RequestCacheEntry : NSObject + +@property(readonly, copy, nullable) NSString *path; +@property(readonly, copy, nullable) id message; + +@end + +@interface MutableRequestCacheEntry : RequestCacheEntry + +@property(copy, nullable) NSString *path; +@property(copy, nullable) id message; + +@end + +@interface ResponseCacheEntry : NSObject + +@property(readonly, copy, nullable) NSDate *deadline; + +@property(readonly, copy, nullable) NSDictionary *headers; +@property(readonly, copy, nullable) id message; +@property(readonly, copy, nullable) NSDictionary *trailers; + +@end + +@interface MutableResponseCacheEntry : ResponseCacheEntry + +@property(copy, nullable) NSDate *deadline; + +@property(copy, nullable) NSDictionary *headers; +@property(copy, nullable) id message; +@property(copy, nullable) NSDictionary *trailers; + +@end + +@interface CacheContext : NSObject + +- (nullable instancetype)init; + +- (nullable ResponseCacheEntry *)getCachedResponseForRequest:(RequestCacheEntry *)request; + +- (void)setCachedResponse:(ResponseCacheEntry *)response forRequest:(RequestCacheEntry *)request; + +@end + +@interface CacheInterceptor : GRPCInterceptor + +- (instancetype)init NS_UNAVAILABLE; + ++ (instancetype)new NS_UNAVAILABLE; + +- (nullable instancetype)initWithInterceptorManager:(GRPCInterceptorManager * _Nonnull)intercepterManager + cacheContext:(CacheContext * _Nonnull)cacheContext NS_DESIGNATED_INITIALIZER; + +// implementation of GRPCInterceptorInterface +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions; +- (void)writeData:(id)data; +- (void)finish; + +// implementation of GRPCResponseHandler +- (void)didReceiveInitialMetadata:(nullable NSDictionary *)initialMetadata; +- (void)didReceiveData:(id)data; +- (void)didCloseWithTrailingMetadata:(nullable NSDictionary *)trailingMetadata + error:(nullable NSError *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m new file mode 100644 index 00000000000..fea770af486 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m @@ -0,0 +1,303 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "CacheInterceptor.h" + +@implementation RequestCacheEntry { + @protected + NSString *_path; + id _message; +} + +@synthesize path = _path; +@synthesize message = _message; + +- (instancetype)initWithPath:(NSString *)path message:(id)message { + if ((self = [super init])) { + _path = [path copy]; + _message = [message copy]; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + return [[RequestCacheEntry allocWithZone:zone] initWithPath:_path message:_message]; +} + +- (BOOL)isEqual:(id)object { + if ([self class] != [object class]) return NO; + RequestCacheEntry *rhs = (RequestCacheEntry *)object; + return ([_path isEqualToString:rhs.path] && [_message isEqual:rhs.message]); +} + +- (NSUInteger)hash { + return _path.hash ^ _message.hash; +} + +@end + +@implementation MutableRequestCacheEntry + +@dynamic path; +@dynamic message; + +- (void)setPath:(NSString *)path { + _path = [path copy]; +} + +- (void)setMessage:(id)message { + _message = [message copy]; +} + +@end + +@implementation ResponseCacheEntry { + @protected + NSDate *_deadline; + NSDictionary *_headers; + id _message; + NSDictionary *_trailers; +} + +@synthesize deadline = _deadline; +@synthesize headers = _headers; +@synthesize message = _message; +@synthesize trailers = _trailers; + +- (instancetype)initWithDeadline:(NSDate *)deadline + headers:(NSDictionary *)headers + message:(id)message + trailers:(NSDictionary *)trailers { + if (([super init])) { + _deadline = [deadline copy]; + _headers = [[NSDictionary alloc] initWithDictionary:headers copyItems:YES]; + _message = [message copy]; + _trailers = [[NSDictionary alloc] initWithDictionary:trailers copyItems:YES]; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + return [[ResponseCacheEntry allocWithZone:zone] initWithDeadline:_deadline + headers:_headers + message:_message + trailers:_trailers]; +} + +@end + +@implementation MutableResponseCacheEntry + +@dynamic deadline; +@dynamic headers; +@dynamic message; +@dynamic trailers; + +- (void)setDeadline:(NSDate *)deadline { + _deadline = [deadline copy]; +} + +- (void)setHeaders:(NSDictionary *)headers { + _headers = [[NSDictionary alloc] initWithDictionary:headers copyItems:YES]; +} + +- (void)setMessage:(id)message { + _message = [message copy]; +} + +- (void)setTrailers:(NSDictionary *)trailers { + _trailers = [[NSDictionary alloc] initWithDictionary:trailers copyItems:YES]; +} + +@end + +@implementation CacheContext { + NSCache *_cache; +} + +- (instancetype)init { + if ((self = [super init])) { + _cache = [[NSCache alloc] init]; + } + return self; +} + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { + return [[CacheInterceptor alloc] initWithInterceptorManager:interceptorManager + cacheContext:self]; +} + +- (ResponseCacheEntry *)getCachedResponseForRequest:(RequestCacheEntry *)request { + ResponseCacheEntry *response = nil; + @synchronized (self) { + response = [_cache objectForKey:request]; + } + return response; +} + +- (void)setCachedResponse:(ResponseCacheEntry *)response + forRequest:(RequestCacheEntry *)request { + @synchronized (self) { + [_cache setObject:response forKey:request]; + } +} + +@end + +@implementation CacheInterceptor { + GRPCInterceptorManager *_manager; + CacheContext *_context; + dispatch_queue_t _dispatchQueue; + + BOOL _cacheable; + BOOL _messageSeen; + GRPCCallOptions *_callOptions; + GRPCRequestOptions *_requestOptions; + id _requestMessage; + MutableRequestCacheEntry *_request; + MutableResponseCacheEntry *_response; +} + +- (dispatch_queue_t)requestDispatchQueue { + return _dispatchQueue; +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager * _Nonnull)intercepterManager + cacheContext:(CacheContext * _Nonnull)cacheContext { + if ((self = [super initWithInterceptorManager:intercepterManager + requestDispatchQueue:dispatch_get_main_queue() + responseDispatchQueue:dispatch_get_main_queue()])) { + _manager = intercepterManager; + _context = cacheContext; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + + _cacheable = YES; + _messageSeen = NO; + _request = nil; + _response = nil; + } + return self; +} + +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { + NSLog(@"start"); + if (requestOptions.safety != GRPCCallSafetyCacheableRequest) { + NSLog(@"no cache"); + _cacheable = NO; + [_manager startNextInterceptorWithRequest:requestOptions callOptions:callOptions]; + } else { + _requestOptions = [requestOptions copy]; + _callOptions = [callOptions copy]; + } +} + +- (void)writeData:(id)data { + NSLog(@"writeData"); + if (!_cacheable) { + [_manager writeNextInterceptorWithData:data]; + } else { + NSAssert(!_messageSeen, @"CacheInterceptor does not support streaming call"); + if (_messageSeen) { + NSLog(@"CacheInterceptor does not support streaming call"); + } + _messageSeen = YES; + _requestMessage = [data copy]; + } +} + +- (void)finish { + NSLog(@"finish"); + if (!_cacheable) { + [_manager finishNextInterceptor]; + } else { + _request = [[MutableRequestCacheEntry alloc] init]; + _request.path = _requestOptions.path; + _request.message = [_requestMessage copy]; + _response = [[_context getCachedResponseForRequest:_request] copy]; + NSLog(@"Read cache for %@", _request); + if (!_response) { + [_manager startNextInterceptorWithRequest:_requestOptions + callOptions:_callOptions]; + [_manager writeNextInterceptorWithData:_requestMessage]; + [_manager finishNextInterceptor]; + } else { + [_manager forwardPreviousInterceptorWithInitialMetadata:_response.headers]; + [_manager forwardPreviousIntercetporWithData:_response.message]; + [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:_response.trailers error:nil]; + [_manager shutDown]; + } + } +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + NSLog(@"initialMetadata"); + if (_cacheable) { + NSDate *deadline = nil; + for (NSString *key in initialMetadata) { + if ([key.lowercaseString isEqualToString:@"cache-control"]) { + NSArray *cacheControls = [initialMetadata[key] componentsSeparatedByString:@","]; + for (NSString *option in cacheControls) { + NSString *trimmedOption = [option stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" "]]; + if ([trimmedOption.lowercaseString isEqualToString:@"no-cache"] || + [trimmedOption.lowercaseString isEqualToString:@"no-store"] || + [trimmedOption.lowercaseString isEqualToString:@"no-transform"]) { + _cacheable = NO; + break; + } else if ([trimmedOption.lowercaseString hasPrefix:@"max-age="]) { + NSArray *components = [trimmedOption componentsSeparatedByString:@"="]; + if (components.count == 2) { + NSUInteger maxAge = components[1].intValue; + deadline = [NSDate dateWithTimeIntervalSinceNow:maxAge]; + } + } + } + } + } + if (_cacheable) { + _response = [[MutableResponseCacheEntry alloc] init]; + _response.headers = [initialMetadata copy]; + _response.deadline = deadline; + } + } + [_manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; +} + +- (void)didReceiveData:(id)data { + NSLog(@"receiveData"); + if (_cacheable) { + _response.message = [data copy]; + } + [_manager forwardPreviousIntercetporWithData:data]; +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + NSLog(@"close"); + if (error == nil && _cacheable) { + _response.trailers = [trailingMetadata copy]; + [_context setCachedResponse:_response forRequest:_request]; + NSLog(@"Write cache for %@", _request); + } + [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; + [_manager shutDown]; +} + +@end diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/Info.plist b/src/objective-c/examples/InterceptorSample/InterceptorSample/Info.plist new file mode 100644 index 00000000000..16be3b68112 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h new file mode 100644 index 00000000000..79de577af81 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m new file mode 100644 index 00000000000..79e53313e55 --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m @@ -0,0 +1,86 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "ViewController.h" + +#import +#import +#import + +#import "CacheInterceptor.h" + +static NSString *const kPackage = @"grpc.testing"; +static NSString *const kService = @"TestService"; + +@interface ViewController () + +@end + +@implementation ViewController { + GRPCCallOptions *_options; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + + id factory = [[CacheContext alloc] init]; + options.interceptorFactories = @[ factory ]; + _options = options; +} + +- (IBAction)tapCall:(id)sender { + GRPCProtoMethod *kUnaryCallMethod = + [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"UnaryCall"]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:@"grpc-test.sandbox.googleapis.com" + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyCacheableRequest]; + + GRPCCall2 *call = [[GRPCCall2 alloc] initWithRequestOptions:requestOptions + responseHandler:self + callOptions:_options]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseSize = 100; + + [call start]; + [call writeData:[request data]]; + [call finish]; + +} + +- (dispatch_queue_t)dispatchQueue { + return dispatch_get_main_queue(); +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + NSLog(@"Header: %@", initialMetadata); +} + +- (void)didReceiveData:(id)data { + NSLog(@"Message: %@", data); +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + NSLog(@"Trailer: %@\nError: %@", trailingMetadata, error); +} + +@end diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m new file mode 100644 index 00000000000..62a9f8e6efb --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m @@ -0,0 +1,26 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/src/objective-c/examples/InterceptorSample/Podfile b/src/objective-c/examples/InterceptorSample/Podfile new file mode 100644 index 00000000000..b20813d32aa --- /dev/null +++ b/src/objective-c/examples/InterceptorSample/Podfile @@ -0,0 +1,31 @@ +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +ROOT_DIR = '../../../..' + +target 'InterceptorSample' do + pod 'gRPC-ProtoRPC', :path => ROOT_DIR + pod 'gRPC', :path => ROOT_DIR + pod 'gRPC-Core', :path => ROOT_DIR + pod 'gRPC-RxLibrary', :path => ROOT_DIR + pod 'RemoteTest', :path => "../RemoteTestClient" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{ROOT_DIR}/src/objective-c" +end + +pre_install do |installer| + grpc_core_spec = installer.pod_targets.find{|t| t.name.start_with?('gRPC-Core')}.root_spec + + src_root = "$(PODS_TARGET_SRCROOT)" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/gpr/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } +end + From cb82833038911e34d7d25dc71d01e7d0a12bae6a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Apr 2019 17:30:19 -0700 Subject: [PATCH 009/676] Add documentation and comments --- src/objective-c/GRPCClient/GRPCInterceptor.h | 117 ++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h index 4ec71f9c271..8e23ffc5361 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.h +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -19,6 +19,90 @@ /** * API for interceptors implementation. This feature is currently EXPERIMENTAL and is subject to * breaking changes without prior notice. + * + * The interceptors in the gRPC system forms a chain. When a call is made by the user, each + * interceptor on the chain has chances to react to events of the call and make necessary + * modifications to the call's parameters, data, metadata, or flow. + * + * + * ----------- + * | GRPCCall2 | + * ----------- + * | + * | + * -------------------------- + * | GRPCInterceptorManager 1 | + * -------------------------- + * | GRPCInterceptor 1 | + * -------------------------- + * | + * ... + * | + * -------------------------- + * | GRPCInterceptorManager N | + * -------------------------- + * | GRPCInterceptor N | + * -------------------------- + * | + * | + * ------------------ + * | GRPCCallInternal | + * ------------------ + * + * The chain of interceptors is initialized when the corresponding GRPCCall2 object or proto call + * object (GRPCUnaryProtoCall and GRPCStreamingProtoCall) is initialized. The initialization of the + * chain is controlled by the property interceptorFactories in the callOptions parameter of the + * corresponding call object. Property interceptorFactories is an array of + * id objects provided by the user. When a call object is initialized, each + * interceptor factory generates an interceptor object for the call. gRPC internally links the + * interceptors with each other and with the actual call object. The order of the interceptors in + * the chain is exactly the same as the order of factory objects in interceptorFactories property. + * All requests (start, write, finish, cancel, receive next) initiated by the user will be processed + * in the order of interceptors, and all responses (initial metadata, data, trailing metadata, write + * data done) are processed in the reverse order. + * + * Each interceptor in the interceptor chain should behave as a user of the next interceptor, and at + * the same time behave as a call to the previous interceptor. Therefore interceptor implementations + * must follow the state transition of gRPC calls and must also forward events that are consistent + * with the current state of the next/previous interceptor. They should also make sure that the + * events they forwarded to the next and previous interceptors will, in the end, make the neighbour + * interceptor terminate correctly and reaches "finished" state. The diagram below shows the state + * transitions. Any event not appearing on the diagram means the event is not permitted for that + * particular state. + * + * writeData + * receiveNextMessages + * didReceiveInitialMetadata + * didReceiveData + * didWriteData + * writeData ----- ----- ---- didReceiveInitialMetadata + * receiveNextMessages | | | | | | didReceiveData + * | V | V | V didWriteData + * ------------- start --------- finish ------------ + * | initialized | -----> | started | --------> | half-close | + * ------------- --------- ------------ + * | | | + * | | didClose | didClose + * |cancel | cancel | cancel + * | V | + * | ---------- | + * --------------> | finished | <-------------- + * ---------- + * | ^ writeData + * | | finish + * ------ cancel + * receiveNextMessages + * + * Events of requests and responses are dispatched to interceptor objects using the interceptor's + * dispatch queue. The dispatch queue should be serial queue to make sure the events are processed + * in order. Interceptor implementations must derive from GRPCInterceptor class. The class makes + * some basic implementation of all methods responding to an event of a call. If an interceptor does + * not care about a particular event, it can use the basic implementation of the GRPCInterceptor + * class, which simply forward the event to the next or previous interceptor in the chain. + * + * The interceptor object should be unique for each call since the call context is not passed to the + * interceptor object in a call event. However, the interceptors can be implemented to share states + * by receiving state sharing object from the factory upon construction. */ #import "GRPCCall.h" @@ -28,24 +112,49 @@ NS_ASSUME_NONNULL_BEGIN @class GRPCInterceptorManager; @class GRPCInterceptor; +/** + * The GRPCInterceptorInterface defines the request events that can occur to an interceptr. + */ @protocol GRPCInterceptorInterface -/** The queue on which all methods of this interceptor should be dispatched on */ +/** + * The queue on which all methods of this interceptor should be dispatched on. The queue must be a + * serial queue. + */ @property(readonly) dispatch_queue_t requestDispatchQueue; +/** + * To start the call. This method will only be called once for each instance. + */ - (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions; +/** + * To write data to the call. + */ - (void)writeData:(id)data; +/** + * To finish the stream of requests. + */ - (void)finish; +/** + * To cancel the call. + */ - (void)cancel; +/** + * To indicate the call that the previous interceptor is ready to receive more messages. + */ - (void)receiveNextMessages:(NSUInteger)numberOfMessages; @end +/** + * An interceptor factory object should be used to create interceptor object for the call at the + * call start time. + */ @protocol GRPCInterceptorFactory /** @@ -56,6 +165,12 @@ NS_ASSUME_NONNULL_BEGIN @end +/** + * The interceptor manager object retains reference to the next and previous interceptor object in + * the interceptor chain, and forward corresponding events to them. When a call terminates, it must + * invoke shutDown method of its corresponding manager so that references to other interceptors can + * be released. + */ @interface GRPCInterceptorManager : NSObject - (instancetype)init NS_UNAVAILABLE; From 6a3ea4934b44db30fde0b518d1be5372612b113f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 24 Apr 2019 17:30:41 -0700 Subject: [PATCH 010/676] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 21 +- src/objective-c/GRPCClient/GRPCCallOptions.h | 2 - src/objective-c/GRPCClient/GRPCCallOptions.m | 14 +- src/objective-c/GRPCClient/GRPCInterceptor.h | 12 +- src/objective-c/GRPCClient/GRPCInterceptor.m | 37 +- .../GRPCClient/private/GRPCCallInternal.m | 18 +- .../InterceptorSample/AppDelegate.h | 4 +- .../InterceptorSample/CacheInterceptor.h | 8 +- .../InterceptorSample/CacheInterceptor.m | 28 +- .../InterceptorSample/ViewController.h | 2 - .../InterceptorSample/ViewController.m | 3 +- .../InterceptorSample/main.m | 4 +- src/objective-c/tests/InteropTests.m | 494 ++++++++++-------- 13 files changed, 341 insertions(+), 306 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index fb4dbdb5d71..40aaea16e56 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -18,8 +18,8 @@ #import "GRPCCall.h" #import "GRPCCall+OAuth2.h" -#import "GRPCInterceptor.h" #import "GRPCCallOptions.h" +#import "GRPCInterceptor.h" #import #import @@ -28,6 +28,8 @@ #include #include +#import "private/GRPCCall+V2API.h" +#import "private/GRPCCallInternal.h" #import "private/GRPCChannelPool.h" #import "private/GRPCCompletionQueue.h" #import "private/GRPCConnectivityMonitor.h" @@ -37,8 +39,6 @@ #import "private/NSData+GRPC.h" #import "private/NSDictionary+GRPC.h" #import "private/NSError+GRPC.h" -#import "private/GRPCCall+V2API.h" -#import "private/GRPCCallInternal.h" // At most 6 ops can be in an op batch for a client: SEND_INITIAL_METADATA, // SEND_MESSAGE, SEND_CLOSE_FROM_CLIENT, RECV_INITIAL_METADATA, RECV_MESSAGE, @@ -142,8 +142,10 @@ const char *kCFStreamVarName = "grpc_cfstream"; [internalCall setResponseHandler:_responseHandler]; } else { for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { - GRPCInterceptorManager *manager = [[GRPCInterceptorManager alloc] initWithNextInerceptor:nextInterceptor]; - GRPCInterceptor *interceptor = [interceptorFactories[i] createInterceptorWithManager:manager]; + GRPCInterceptorManager *manager = + [[GRPCInterceptorManager alloc] initWithNextInerceptor:nextInterceptor]; + GRPCInterceptor *interceptor = + [interceptorFactories[i] createInterceptorWithManager:manager]; NSAssert(interceptor != nil, @"Failed to create interceptor"); if (interceptor == nil) { return nil; @@ -180,8 +182,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCCallOptions *callOptions = [_actualCallOptions copy]; if ([copiedFirstInterceptor respondsToSelector:@selector(startWithRequestOptions:callOptions:)]) { dispatch_async(copiedFirstInterceptor.requestDispatchQueue, ^{ - [copiedFirstInterceptor startWithRequestOptions:requestOptions - callOptions:callOptions]; + [copiedFirstInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; }); } } @@ -200,7 +201,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)writeData:(id)data { id copiedFirstInterceptor; - @synchronized (self) { + @synchronized(self) { copiedFirstInterceptor = _firstInterceptor; } if ([copiedFirstInterceptor respondsToSelector:@selector(writeData:)]) { @@ -212,7 +213,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)finish { id copiedFirstInterceptor; - @synchronized (self) { + @synchronized(self) { copiedFirstInterceptor = _firstInterceptor; } if ([copiedFirstInterceptor respondsToSelector:@selector(finish)]) { @@ -224,7 +225,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)receiveNextMessages:(NSUInteger)numberOfMessages { id copiedFirstInterceptor; - @synchronized (self) { + @synchronized(self) { copiedFirstInterceptor = _firstInterceptor; } if ([copiedFirstInterceptor respondsToSelector:@selector(receiveNextMessages:)]) { diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 6f985c8d952..98511e3f5cb 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -106,7 +106,6 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(copy, readonly) NSArray *interceptorFactories; - // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** @@ -270,7 +269,6 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { */ @property(copy, readwrite) NSArray *interceptorFactories; - // OAuth2 parameters. Users of gRPC may specify one of the following two parameters. /** diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 5a270407620..392e42a9d47 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -115,7 +115,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout - flowControlEnabled:kDefaultFlowControlEnabled + flowControlEnabled:kDefaultFlowControlEnabled interceptorFactories:kDefaultInterceptorFactories oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider @@ -142,7 +142,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)initWithServerAuthority:(NSString *)serverAuthority timeout:(NSTimeInterval)timeout - flowControlEnabled:(BOOL)flowControlEnabled + flowControlEnabled:(BOOL)flowControlEnabled interceptorFactories:(NSArray *)interceptorFactories oauth2AccessToken:(NSString *)oauth2AccessToken authTokenProvider:(id)authTokenProvider @@ -205,7 +205,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout - flowControlEnabled:_flowControlEnabled + flowControlEnabled:_flowControlEnabled interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider @@ -235,7 +235,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:[_serverAuthority copy] timeout:_timeout - flowControlEnabled:_flowControlEnabled + flowControlEnabled:_flowControlEnabled interceptorFactories:_interceptorFactories oauth2AccessToken:[_oauth2AccessToken copy] authTokenProvider:_authTokenProvider @@ -344,7 +344,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { - (instancetype)init { return [self initWithServerAuthority:kDefaultServerAuthority timeout:kDefaultTimeout - flowControlEnabled:kDefaultFlowControlEnabled + flowControlEnabled:kDefaultFlowControlEnabled interceptorFactories:kDefaultInterceptorFactories oauth2AccessToken:kDefaultOauth2AccessToken authTokenProvider:kDefaultAuthTokenProvider @@ -373,7 +373,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCCallOptions *newOptions = [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout - flowControlEnabled:_flowControlEnabled + flowControlEnabled:_flowControlEnabled interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider @@ -403,7 +403,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority timeout:_timeout - flowControlEnabled:_flowControlEnabled + flowControlEnabled:_flowControlEnabled interceptorFactories:_interceptorFactories oauth2AccessToken:_oauth2AccessToken authTokenProvider:_authTokenProvider diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h index 8e23ffc5361..931f6e4aa5a 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.h +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -175,9 +175,10 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; -- (nullable instancetype)initWithNextInerceptor:(id)nextInterceptor NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithNextInerceptor:(id)nextInterceptor + NS_DESIGNATED_INITIALIZER; /** Set the previous interceptor in the chain. Can only be set once. */ - (void)setPreviousInterceptor:(id)previousInterceptor; @@ -213,7 +214,7 @@ NS_ASSUME_NONNULL_BEGIN /** Forward call close and trailing metadata to the previous interceptor in the chain */ - (void)forwardPreviousInterceptorCloseWithTrailingMetadata: -(nullable NSDictionary *)trailingMetadata + (nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error; /** Forward write completion to the previous interceptor in the chain */ @@ -235,7 +236,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; /** * Initialize the interceptor with the next interceptor in the chain, and provide the dispatch queue @@ -243,7 +244,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (nullable instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager requestDispatchQueue:(dispatch_queue_t)requestDispatchQueue - responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue NS_DESIGNATED_INITIALIZER; + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue + NS_DESIGNATED_INITIALIZER; // Default implementation of GRPCInterceptorInterface diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.m b/src/objective-c/GRPCClient/GRPCInterceptor.m index ac0b69f14eb..1c1f0b53114 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.m +++ b/src/objective-c/GRPCClient/GRPCInterceptor.m @@ -47,8 +47,7 @@ if ([_nextInterceptor respondsToSelector:@selector(startWithRequestOptions:callOptions:)]) { id copiedNextInterceptor = _nextInterceptor; dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor startWithRequestOptions:requestOptions - callOptions:callOptions]; + [copiedNextInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; }); } } @@ -114,13 +113,12 @@ /** Forward call close and trailing metadata to the previous interceptor in the chain */ - (void)forwardPreviousInterceptorCloseWithTrailingMetadata: -(nullable NSDictionary *)trailingMetadata + (nullable NSDictionary *)trailingMetadata error:(nullable NSError *)error { if ([_previousInterceptor respondsToSelector:@selector(didCloseWithTrailingMetadata:error:)]) { id copiedPreviousInterceptor = _previousInterceptor; dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ - [copiedPreviousInterceptor didCloseWithTrailingMetadata:trailingMetadata - error:error]; + [copiedPreviousInterceptor didCloseWithTrailingMetadata:trailingMetadata error:error]; }); } } @@ -165,8 +163,7 @@ - (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { - [_manager startNextInterceptorWithRequest:requestOptions - callOptions:callOptions]; + [_manager startNextInterceptorWithRequest:requestOptions callOptions:callOptions]; } - (void)writeData:(id)data { @@ -179,13 +176,15 @@ - (void)cancel { [_manager cancelNextInterceptor]; - [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:nil - error:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeCancelled - userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled" - }]]; + [_manager + forwardPreviousInterceptorCloseWithTrailingMetadata:nil + error:[NSError + errorWithDomain:kGRPCErrorDomain + code:GRPCErrorCodeCancelled + userInfo:@{ + NSLocalizedDescriptionKey : + @"Canceled" + }]]; [_manager shutDown]; } @@ -193,13 +192,13 @@ [_manager receiveNextInterceptorMessages:numberOfMessages]; } - - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { [_manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; } - (void)didReceiveRawMessage:(id)message { - NSAssert(NO, @"The method didReceiveRawMessage is deprecated and cannot be used with interceptor"); + NSAssert(NO, + @"The method didReceiveRawMessage is deprecated and cannot be used with interceptor"); NSLog(@"The method didReceiveRawMessage is deprecated and cannot be used with interceptor"); abort(); } @@ -208,10 +207,8 @@ [_manager forwardPreviousIntercetporWithData:data]; } -- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata - error:(NSError *)error { - [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata - error:error]; +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; [_manager shutDown]; } diff --git a/src/objective-c/GRPCClient/private/GRPCCallInternal.m b/src/objective-c/GRPCClient/private/GRPCCallInternal.m index 06912cc7fa9..e4edcedf36c 100644 --- a/src/objective-c/GRPCClient/private/GRPCCallInternal.m +++ b/src/objective-c/GRPCClient/private/GRPCCallInternal.m @@ -35,12 +35,12 @@ - (instancetype)init { if ((self = [super init])) { - // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above + // Set queue QoS only when iOS version is 8.0 or above and Xcode version is 9.0 or above #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 if (@available(iOS 8.0, macOS 10.10, *)) { _dispatchQueue = dispatch_queue_create( - NULL, - dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); + NULL, + dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0)); } else { #else { @@ -53,7 +53,7 @@ } - (void)setResponseHandler:(id)responseHandler { - @synchronized (self) { + @synchronized(self) { NSAssert(!_started, @"Call already started."); if (_started) { return; @@ -84,7 +84,7 @@ return; } - @synchronized (self) { + @synchronized(self) { NSAssert(_handler != nil, @"Response handler required."); if (_handler == nil) { NSLog(@"Invalid response handler."); @@ -172,7 +172,7 @@ } }; id responseWriteable = - [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; + [[GRXWriteable alloc] initWithValueHandler:valueHandler completionHandler:completionHandler]; [copiedCall startWithWriteable:responseWriteable]; } @@ -197,9 +197,9 @@ error:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeCancelled userInfo:@{ - NSLocalizedDescriptionKey : - @"Canceled by app" - }]]; + NSLocalizedDescriptionKey : + @"Canceled by app" + }]]; }); } else { _handler = nil; diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h index c4e433787e6..183abcf4ec8 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.h @@ -18,8 +18,8 @@ #import -@interface AppDelegate : UIResponder +@interface AppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; +@property(strong, nonatomic) UIWindow* window; @end diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h index a2c9d668c14..a1de74cdb1f 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.h @@ -68,10 +68,12 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; ++ (instancetype) new NS_UNAVAILABLE; -- (nullable instancetype)initWithInterceptorManager:(GRPCInterceptorManager * _Nonnull)intercepterManager - cacheContext:(CacheContext * _Nonnull)cacheContext NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithInterceptorManager: + (GRPCInterceptorManager *_Nonnull)intercepterManager + cacheContext:(CacheContext *_Nonnull)cacheContext + NS_DESIGNATED_INITIALIZER; // implementation of GRPCInterceptorInterface - (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m index fea770af486..082bd303dec 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m @@ -19,7 +19,7 @@ #import "CacheInterceptor.h" @implementation RequestCacheEntry { - @protected + @protected NSString *_path; id _message; } @@ -67,7 +67,7 @@ @end @implementation ResponseCacheEntry { - @protected + @protected NSDate *_deadline; NSDictionary *_headers; id _message; @@ -138,21 +138,19 @@ } - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { - return [[CacheInterceptor alloc] initWithInterceptorManager:interceptorManager - cacheContext:self]; + return [[CacheInterceptor alloc] initWithInterceptorManager:interceptorManager cacheContext:self]; } - (ResponseCacheEntry *)getCachedResponseForRequest:(RequestCacheEntry *)request { ResponseCacheEntry *response = nil; - @synchronized (self) { + @synchronized(self) { response = [_cache objectForKey:request]; } return response; } -- (void)setCachedResponse:(ResponseCacheEntry *)response - forRequest:(RequestCacheEntry *)request { - @synchronized (self) { +- (void)setCachedResponse:(ResponseCacheEntry *)response forRequest:(RequestCacheEntry *)request { + @synchronized(self) { [_cache setObject:response forKey:request]; } } @@ -181,8 +179,8 @@ return _dispatchQueue; } -- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager * _Nonnull)intercepterManager - cacheContext:(CacheContext * _Nonnull)cacheContext { +- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *_Nonnull)intercepterManager + cacheContext:(CacheContext *_Nonnull)cacheContext { if ((self = [super initWithInterceptorManager:intercepterManager requestDispatchQueue:dispatch_get_main_queue() responseDispatchQueue:dispatch_get_main_queue()])) { @@ -198,7 +196,8 @@ return self; } -- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { +- (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions + callOptions:(GRPCCallOptions *)callOptions { NSLog(@"start"); if (requestOptions.safety != GRPCCallSafetyCacheableRequest) { NSLog(@"no cache"); @@ -235,8 +234,7 @@ _response = [[_context getCachedResponseForRequest:_request] copy]; NSLog(@"Read cache for %@", _request); if (!_response) { - [_manager startNextInterceptorWithRequest:_requestOptions - callOptions:_callOptions]; + [_manager startNextInterceptorWithRequest:_requestOptions callOptions:_callOptions]; [_manager writeNextInterceptorWithData:_requestMessage]; [_manager finishNextInterceptor]; } else { @@ -256,7 +254,9 @@ if ([key.lowercaseString isEqualToString:@"cache-control"]) { NSArray *cacheControls = [initialMetadata[key] componentsSeparatedByString:@","]; for (NSString *option in cacheControls) { - NSString *trimmedOption = [option stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" "]]; + NSString *trimmedOption = + [option stringByTrimmingCharactersInSet:[NSCharacterSet + characterSetWithCharactersInString:@" "]]; if ([trimmedOption.lowercaseString isEqualToString:@"no-cache"] || [trimmedOption.lowercaseString isEqualToString:@"no-store"] || [trimmedOption.lowercaseString isEqualToString:@"no-transform"]) { diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h index 79de577af81..0aa0b2a73a7 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.h @@ -20,6 +20,4 @@ @interface ViewController : UIViewController - @end - diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m index 79e53313e55..9da6dedbf9e 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/ViewController.m @@ -19,8 +19,8 @@ #import "ViewController.h" #import -#import #import +#import #import "CacheInterceptor.h" @@ -64,7 +64,6 @@ static NSString *const kService = @"TestService"; [call start]; [call writeData:[request data]]; [call finish]; - } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m index 62a9f8e6efb..2797c6f17f2 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/main.m @@ -19,8 +19,8 @@ #import #import "AppDelegate.h" -int main(int argc, char * argv[]) { +int main(int argc, char* argv[]) { @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 42365d2be2c..93316c0ff5a 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -171,15 +171,20 @@ BOOL isRemoteInteropTest(NSString *host) { @interface HookInterceptorFactory : NSObject -- (instancetype)initWithDispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook - receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; +- (instancetype) + initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook +receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; @@ -187,40 +192,53 @@ BOOL isRemoteInteropTest(NSString *host) { @interface HookIntercetpor : GRPCInterceptor -- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - dispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook - receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; +- (instancetype) +initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + dispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; @end @implementation HookInterceptorFactory { - void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); + void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager); void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); void (^_finishHook)(GRPCInterceptorManager *manager); void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); - void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); + void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); dispatch_queue_t _dispatchQueue; } -- (instancetype)initWithDispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook - receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { +- (instancetype) + initWithDispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook +receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { if ((self = [super init])) { _dispatchQueue = dispatchQueue; _startHook = startHook; @@ -252,13 +270,15 @@ BOOL isRemoteInteropTest(NSString *host) { @end @implementation HookIntercetpor { - void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); + void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager); void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); void (^_finishHook)(GRPCInterceptorManager *manager); void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); - void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); + void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); GRPCInterceptorManager *_manager; dispatch_queue_t _dispatchQueue; @@ -272,17 +292,25 @@ BOOL isRemoteInteropTest(NSString *host) { return _dispatchQueue; } -- (instancetype)initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - dispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook - receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { - if ((self = [super initWithInterceptorManager:interceptorManager requestDispatchQueue:dispatchQueue responseDispatchQueue:dispatchQueue])) { +- (instancetype) +initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager + dispatchQueue:(dispatch_queue_t)dispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { + if ((self = [super initWithInterceptorManager:interceptorManager + requestDispatchQueue:dispatchQueue + responseDispatchQueue:dispatchQueue])) { _startHook = startHook; _writeDataHook = writeDataHook; _finishHook = finishHook; @@ -1271,39 +1299,39 @@ BOOL isRemoteInteropTest(NSString *host) { options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init] ]; __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertLessThan(index, 4, - @"More than 4 responses received."); - id expected = [RMTStreamingOutputCallResponse - messageWithPayloadSize:responses[index]]; - XCTAssertEqualObjects(message, expected); - index += 1; - if (index < 4) { - id request = [RMTStreamingOutputCallRequest - messageWithPayloadSize:requests[index] - requestedResponseSize:responses[index]]; - [call writeMessage:request]; - } else { - [call finish]; - } - // DEBUG - NSLog(@"Received message"); - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNil(error, - @"Finished with unexpected error: %@", - error); - XCTAssertEqual(index, 4, - @"Received %i responses instead of 4.", - index); - [expectation fulfill]; - // DEBUG - NSLog(@"Received close"); - }] - callOptions:options]; + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeMessage:request]; + } else { + [call finish]; + } + // DEBUG + NSLog(@"Received message"); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + // DEBUG + NSLog(@"Received close"); + }] + callOptions:options]; [call start]; [call writeMessage:request]; @@ -1322,54 +1350,56 @@ BOOL isRemoteInteropTest(NSString *host) { __block NSUInteger responseDataCount = 0; __block NSUInteger responseCloseCount = 0; __block NSUInteger didWriteDataCount = 0; - id factory = - [[HookInterceptorFactory alloc] initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { - startCount++; - NSLog(@"Interceptor - started call, %@, %@", requestOptions, callOptions); - XCTAssertEqualObjects(requestOptions.host, [[self class] host]); - XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); - XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); - [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; - } - writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { - writeDataCount++; - NSLog(@"Interceptor - send data, %@", data); - XCTAssertNotEqual(data.length, 0); - [manager writeNextInterceptorWithData:data]; - } - finishHook:^(GRPCInterceptorManager *manager) { - finishCount++; - NSLog(@"Interceptor - finish call"); - [manager finishNextInterceptor]; - } - receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { - receiveNextMessageCount++; - NSLog(@"Interceptor - receive next messages, %lu", (unsigned long)numberOfMessages); - [manager receiveNextInterceptorMessages:numberOfMessages]; - } - responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { - responseHeaderCount++; - NSLog(@"Interceptor - received initial metadata, %@", initialMetadata); - [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; - } - responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { - responseDataCount++; - NSLog(@"Interceptor - received data, %@", data); - XCTAssertNotEqual(data.length, 0); - [manager forwardPreviousIntercetporWithData:data]; - } - responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { - responseCloseCount++; - NSLog(@"Interceptor - received close, %@, %@", trailingMetadata, error); - [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata - error:error]; - } - didWriteDataHook:^(GRPCInterceptorManager *manager) { - didWriteDataCount++; - NSLog(@"Interceptor - received did-write-data"); - [manager forwardPreviousInterceptorDidWriteData]; - }]; + id factory = [[HookInterceptorFactory alloc] + initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + startCount++; + NSLog(@"Interceptor - started call, %@, %@", requestOptions, callOptions); + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] + callOptions:[callOptions copy]]; + } + writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataCount++; + NSLog(@"Interceptor - send data, %@", data); + XCTAssertNotEqual(data.length, 0); + [manager writeNextInterceptorWithData:data]; + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + NSLog(@"Interceptor - finish call"); + [manager finishNextInterceptor]; + } + receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { + receiveNextMessageCount++; + NSLog(@"Interceptor - receive next messages, %lu", (unsigned long)numberOfMessages); + [manager receiveNextInterceptorMessages:numberOfMessages]; + } + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + NSLog(@"Interceptor - received initial metadata, %@", initialMetadata); + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataCount++; + NSLog(@"Interceptor - received data, %@", data); + XCTAssertNotEqual(data.length, 0); + [manager forwardPreviousIntercetporWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager) { + responseCloseCount++; + NSLog(@"Interceptor - received close, %@, %@", trailingMetadata, error); + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; + } + didWriteDataHook:^(GRPCInterceptorManager *manager) { + didWriteDataCount++; + NSLog(@"Interceptor - received did-write-data"); + [manager forwardPreviousInterceptorDidWriteData]; + }]; NSArray *requests = @[ @1, @2, @3, @4 ]; NSArray *responses = @[ @1, @2, @3, @4 ]; @@ -1387,41 +1417,41 @@ BOOL isRemoteInteropTest(NSString *host) { __block BOOL canWriteData = NO; __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertLessThan(index, 4, - @"More than 4 responses received."); - id expected = [RMTStreamingOutputCallResponse - messageWithPayloadSize:responses[index]]; - XCTAssertEqualObjects(message, expected); - index += 1; - if (index < 4) { - id request = [RMTStreamingOutputCallRequest - messageWithPayloadSize:requests[index] - requestedResponseSize:responses[index]]; - XCTAssertTrue(canWriteData); - canWriteData = NO; - [call writeMessage:request]; - [call receiveNextMessage]; - } else { - [call finish]; - } - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNil(error, - @"Finished with unexpected error: %@", - error); - XCTAssertEqual(index, 4, - @"Received %i responses instead of 4.", - index); - [expectation fulfill]; - } - writeMessageCallback:^{ - canWriteData = YES; - }] - callOptions:options]; + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; [call start]; [call receiveNextMessage]; [call writeMessage:request]; @@ -1453,45 +1483,53 @@ BOOL isRemoteInteropTest(NSString *host) { __block NSUInteger responseHeaderCount = 0; __block NSUInteger responseDataCount = 0; __block NSUInteger responseCloseCount = 0; - id factory = - [[HookInterceptorFactory alloc] initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { - startCount++; - [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; - } - writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { - writeDataCount++; - if (index < kCancelAfterWrites) { - [manager writeNextInterceptorWithData:data]; - } else if (index == kCancelAfterWrites) { - [manager cancelNextInterceptor]; - [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; - } else { // (index > kCancelAfterWrites) - [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; - } - } - finishHook:^(GRPCInterceptorManager *manager) { - finishCount++; - // finish must happen after the hijacking, so directly reply with a close - [manager forwardPreviousInterceptorCloseWithTrailingMetadata:@{ @"grpc-status" : @"0" } error:nil]; - } - receiveNextMessagesHook:nil - responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { - responseHeaderCount++; - [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; - } - responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { - responseDataCount++; - [manager forwardPreviousIntercetporWithData:data]; - } - responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { - responseCloseCount++; - // since we canceled the call, it should return cancel error - XCTAssertNil(trailingMetadata); - XCTAssertNotNil(error); - XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); - } - didWriteDataHook:nil]; + id factory = [[HookInterceptorFactory alloc] + initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + startCount++; + [manager startNextInterceptorWithRequest:[requestOptions copy] + callOptions:[callOptions copy]]; + } + writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataCount++; + if (index < kCancelAfterWrites) { + [manager writeNextInterceptorWithData:data]; + } else if (index == kCancelAfterWrites) { + [manager cancelNextInterceptor]; + [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]] + data]]; + } else { // (index > kCancelAfterWrites) + [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]] + data]]; + } + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + // finish must happen after the hijacking, so directly reply with a close + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:@{@"grpc-status" : @"0"} + error:nil]; + } + receiveNextMessagesHook:nil + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataCount++; + [manager forwardPreviousIntercetporWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager) { + responseCloseCount++; + // since we canceled the call, it should return cancel error + XCTAssertNil(trailingMetadata); + XCTAssertNotNil(error); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + } + didWriteDataHook:nil]; NSArray *requests = @[ @1, @2, @3, @4 ]; @@ -1504,36 +1542,36 @@ BOOL isRemoteInteropTest(NSString *host) { options.interceptorFactories = @[ [[DefaultInterceptorFactory alloc] init], factory ]; __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertLessThan(index, 4, - @"More than 4 responses received."); - id expected = [RMTStreamingOutputCallResponse - messageWithPayloadSize:responses[index]]; - XCTAssertEqualObjects(message, expected); - index += 1; - if (index < 4) { - id request = [RMTStreamingOutputCallRequest - messageWithPayloadSize:requests[index] - requestedResponseSize:responses[index]]; - [call writeMessage:request]; - [call receiveNextMessage]; - } else { - [call finish]; - } - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNil(error, - @"Finished with unexpected error: %@", - error); - XCTAssertEqual(index, 4, - @"Received %i responses instead of 4.", - index); - [expectation fulfill]; - }] - callOptions:options]; + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + id expected = [RMTStreamingOutputCallResponse + messageWithPayloadSize:responses[index]]; + XCTAssertEqualObjects(message, expected); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + XCTAssertEqual(index, 4, + @"Received %i responses instead of 4.", + index); + [expectation fulfill]; + }] + callOptions:options]; [call start]; [call receiveNextMessage]; [call writeMessage:request]; From 8f74abcd2d9eaf6ed35ef783346463fc4f1de73f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 26 Apr 2019 14:54:44 -0700 Subject: [PATCH 011/676] Add script to run build tests of examples --- src/objective-c/tests/examples_build_test.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 src/objective-c/tests/examples_build_test.sh diff --git a/src/objective-c/tests/examples_build_test.sh b/src/objective-c/tests/examples_build_test.sh new file mode 100755 index 00000000000..7bf4d67d019 --- /dev/null +++ b/src/objective-c/tests/examples_build_test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -ex + +SCHEME=HelloWorld EXAMPLE_PATH=examples/objective-c/helloworld ./build_one_example.sh +SCHEME=RouteGuideClient EXAMPLE_PATH=examples/objective-c/route_guide ./build_one_example.sh +SCHEME=AuthSample EXAMPLE_PATH=examples/objective-c/auth_sample ./build_one_example.sh From a7a380c69b61faa4d4f55d4f3fde668308c6bce3 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 29 Apr 2019 15:09:07 -0700 Subject: [PATCH 012/676] Delay the creation of Alarm in the callback-based qps client. The alarm is only used in the fixed-load scenarios, but its construction is a major point of contention in both the closed-loop and fixed-load scenarios. Delay its creation to when it is going to be used, which will get rid of the contention in the closed-loop scenarios. --- test/cpp/qps/client_callback.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index dcfa2dbf875..ac70894712e 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -43,13 +43,14 @@ namespace testing { * Maintains context info per RPC */ struct CallbackClientRpcContext { - CallbackClientRpcContext(BenchmarkService::Stub* stub) : stub_(stub) {} + CallbackClientRpcContext(BenchmarkService::Stub* stub) + : alarm_(nullptr), stub_(stub) {} ~CallbackClientRpcContext() {} SimpleResponse response_; ClientContext context_; - Alarm alarm_; + std::unique_ptr alarm_; BenchmarkService::Stub* stub_; }; @@ -169,7 +170,10 @@ class CallbackUnaryClient final : public CallbackClient { gpr_timespec next_issue_time = NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time - ctx_[vector_idx]->alarm_.experimental().Set( + if (ctx_[vector_idx]->alarm_ == nullptr) { + ctx_[vector_idx]->alarm_.reset(new Alarm); + } + ctx_[vector_idx]->alarm_->experimental().Set( next_issue_time, [this, t, vector_idx](bool ok) { IssueUnaryCallbackRpc(t, vector_idx); }); @@ -313,7 +317,10 @@ class CallbackStreamingPingPongReactor final gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time - ctx_->alarm_.experimental().Set(next_issue_time, + if (ctx_->alarm_ == nullptr) { + ctx_->alarm_.reset(new Alarm); + } + ctx_->alarm_->experimental().Set(next_issue_time, [this](bool ok) { StartNewRpc(); }); } else { StartNewRpc(); From 3b5c470bf16ff61a551ef820df70a753d0545517 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 29 Apr 2019 15:19:55 -0700 Subject: [PATCH 013/676] Clang format. --- test/cpp/qps/client_callback.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index ac70894712e..e61e36c9ee1 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -321,7 +321,7 @@ class CallbackStreamingPingPongReactor final ctx_->alarm_.reset(new Alarm); } ctx_->alarm_->experimental().Set(next_issue_time, - [this](bool ok) { StartNewRpc(); }); + [this](bool ok) { StartNewRpc(); }); } else { StartNewRpc(); } From aafa4c48e5a07d87c5df9b6c0e1a92df6fd8dbd2 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 29 Apr 2019 16:10:53 -0700 Subject: [PATCH 014/676] Fix another call of Alarm::experimental()::Set. --- test/cpp/qps/client_callback.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index e61e36c9ee1..ade23e13a72 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -293,7 +293,10 @@ class CallbackStreamingPingPongReactor final gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time - ctx_->alarm_.experimental().Set(next_issue_time, [this](bool ok) { + if (ctx_->alarm_ == nullptr) { + ctx_->alarm_.reset(new Alarm); + } + ctx_->alarm_->experimental().Set(next_issue_time, [this](bool ok) { write_time_ = UsageTimer::Now(); StartWrite(client_->request()); }); From 7d55a8a904010cdb2b03fb1edddf8522ad5e9f69 Mon Sep 17 00:00:00 2001 From: Yusuke Sato Date: Tue, 30 Apr 2019 15:24:50 +0900 Subject: [PATCH 015/676] Fix a typo in the GRPC::RpcServer constructor description --- src/ruby/lib/grpc/generic/rpc_server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 3d34419643e..a566afa0bc2 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -210,7 +210,7 @@ module GRPC # A server arguments hash to be passed down to the underlying core server # # * interceptors: - # Am array of GRPC::ServerInterceptor objects that will be used for + # An array of GRPC::ServerInterceptor objects that will be used for # intercepting server handlers to provide extra functionality. # Interceptors are an EXPERIMENTAL API. # From 99533ab52b30e4055eb6ee034a8de81f7cb863a8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 25 Apr 2019 16:40:49 -0700 Subject: [PATCH 016/676] Reorganize ObjC tests --- src/objective-c/tests/APIv2Tests/Info.plist | 22 - src/objective-c/tests/ChannelTests/Info.plist | 22 - .../tests/CoreCronetEnd2EndTests/Info.plist | 24 - .../CoreCronetEnd2EndTests.mm | 0 .../CronetUnitTests.mm} | 4 +- .../InteropTestsRemoteWithCronet.m | 0 .../tests/CronetUnitTests/Info.plist | 24 - .../tests/{ => InteropTests}/InteropTests.h | 0 .../tests/{ => InteropTests}/InteropTests.m | 77 +- .../InteropTests/InteropTestsBlockCallbacks.h | 33 + .../InteropTests/InteropTestsBlockCallbacks.m | 80 + .../InteropTestsLocalCleartext.m | 0 .../{ => InteropTests}/InteropTestsLocalSSL.m | 0 .../InteropTestsMultipleChannels.m | 268 ++ .../{ => InteropTests}/InteropTestsRemote.m | 0 .../tests/InteropTestsCallOptions/Info.plist | 22 - .../InteropTestsCallOptions.m | 116 - .../InteropTestsMultipleChannels/Info.plist | 22 - .../InteropTestsMultipleChannels.m | 259 -- .../InteropTestsRemoteWithCronet/Info.plist | 24 - src/objective-c/tests/Podfile | 85 +- src/objective-c/tests/Tests.m | 25 - .../tests/Tests.xcodeproj/project.pbxproj | 3998 +++-------------- .../xcshareddata/xcschemes/AllTests.xcscheme | 110 - .../xcschemes/ChannelTests.xcscheme | 90 - .../xcschemes/CoreCronetEnd2EndTests.xcscheme | 101 - .../CoreCronetEnd2EndTests_Asan.xcscheme | 60 - .../CoreCronetEnd2EndTests_Tsan.xcscheme | 59 - ...Iv2Tests.xcscheme => CronetTests.xcscheme} | 30 +- .../xcschemes/CronetUnitTests.xcscheme | 56 - ...sRemote.xcscheme => InteropTests.xcscheme} | 46 +- .../InteropTestsCallOptions.xcscheme | 56 - .../InteropTestsLocalCleartext.xcscheme | 95 - ...nteropTestsLocalCleartextCFStream.xcscheme | 63 - .../xcschemes/InteropTestsLocalSSL.xcscheme | 95 - .../InteropTestsLocalSSLCFStream.xcscheme | 63 - .../InteropTestsMultipleChannels.xcscheme | 56 - .../InteropTestsRemoteCFStream.xcscheme | 61 - .../InteropTestsRemoteWithCronet.xcscheme | 104 - .../xcshareddata/xcschemes/MacTests.xcscheme | 2 +- .../xcschemes/RxLibraryUnitTests.xcscheme | 90 - .../xcshareddata/xcschemes/Tests.xcscheme | 80 - .../xcshareddata/xcschemes/UnitTests.xcscheme | 6 +- .../{APIv2Tests => UnitTests}/APIv2Tests.m | 0 .../ChannelPoolTest.m | 0 .../ChannelTests.m | 0 .../tests/{ => UnitTests}/GRPCClientTests.m | 2 +- src/objective-c/tests/UnitTests/Info.plist | 22 - .../{UnitTests.m => NSErrorUnitTests.m} | 4 +- .../{ => UnitTests}/RxLibraryUnitTests.m | 0 src/objective-c/tests/run_tests.sh | 128 +- 51 files changed, 1100 insertions(+), 5484 deletions(-) delete mode 100644 src/objective-c/tests/APIv2Tests/Info.plist delete mode 100644 src/objective-c/tests/ChannelTests/Info.plist delete mode 100644 src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist rename src/objective-c/tests/{CoreCronetEnd2EndTests => CronetTests}/CoreCronetEnd2EndTests.mm (100%) rename src/objective-c/tests/{CronetUnitTests/CronetUnitTests.m => CronetTests/CronetUnitTests.mm} (99%) rename src/objective-c/tests/{InteropTestsRemoteWithCronet => CronetTests}/InteropTestsRemoteWithCronet.m (100%) delete mode 100644 src/objective-c/tests/CronetUnitTests/Info.plist rename src/objective-c/tests/{ => InteropTests}/InteropTests.h (100%) rename src/objective-c/tests/{ => InteropTests}/InteropTests.m (94%) create mode 100644 src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.h create mode 100644 src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.m rename src/objective-c/tests/{ => InteropTests}/InteropTestsLocalCleartext.m (100%) rename src/objective-c/tests/{ => InteropTests}/InteropTestsLocalSSL.m (100%) create mode 100644 src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m rename src/objective-c/tests/{ => InteropTests}/InteropTestsRemote.m (100%) delete mode 100644 src/objective-c/tests/InteropTestsCallOptions/Info.plist delete mode 100644 src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m delete mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/Info.plist delete mode 100644 src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m delete mode 100644 src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist delete mode 100644 src/objective-c/tests/Tests.m delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Asan.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Tsan.xcscheme rename src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/{APIv2Tests.xcscheme => CronetTests.xcscheme} (77%) delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetUnitTests.xcscheme rename src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/{InteropTestsRemote.xcscheme => InteropTests.xcscheme} (75%) delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsCallOptions.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/RxLibraryUnitTests.xcscheme delete mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme rename src/objective-c/tests/{APIv2Tests => UnitTests}/APIv2Tests.m (100%) rename src/objective-c/tests/{ChannelTests => UnitTests}/ChannelPoolTest.m (100%) rename src/objective-c/tests/{ChannelTests => UnitTests}/ChannelTests.m (100%) rename src/objective-c/tests/{ => UnitTests}/GRPCClientTests.m (99%) delete mode 100644 src/objective-c/tests/UnitTests/Info.plist rename src/objective-c/tests/UnitTests/{UnitTests.m => NSErrorUnitTests.m} (96%) rename src/objective-c/tests/{ => UnitTests}/RxLibraryUnitTests.m (100%) diff --git a/src/objective-c/tests/APIv2Tests/Info.plist b/src/objective-c/tests/APIv2Tests/Info.plist deleted file mode 100644 index 6c40a6cd0c4..00000000000 --- a/src/objective-c/tests/APIv2Tests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/ChannelTests/Info.plist b/src/objective-c/tests/ChannelTests/Info.plist deleted file mode 100644 index 6c40a6cd0c4..00000000000 --- a/src/objective-c/tests/ChannelTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist b/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist deleted file mode 100644 index fbeeb96ba6c..00000000000 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - gRPC.$(PRODUCT_NAME:rfc1034identifier) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm similarity index 100% rename from src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm rename to src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetTests/CronetUnitTests.mm similarity index 99% rename from src/objective-c/tests/CronetUnitTests/CronetUnitTests.m rename to src/objective-c/tests/CronetTests/CronetUnitTests.mm index d732bc6ba99..2a861032caf 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -37,9 +37,9 @@ #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" +#define GRPC_SHADOW_BORINGSSL_SYMBOLS #import "src/core/tsi/grpc_shadow_boringssl.h" - -#import +#import " static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m similarity index 100% rename from src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m rename to src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m diff --git a/src/objective-c/tests/CronetUnitTests/Info.plist b/src/objective-c/tests/CronetUnitTests/Info.plist deleted file mode 100644 index ba72822e872..00000000000 --- a/src/objective-c/tests/CronetUnitTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests/InteropTests.h similarity index 100% rename from src/objective-c/tests/InteropTests.h rename to src/objective-c/tests/InteropTests/InteropTests.h diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m similarity index 94% rename from src/objective-c/tests/InteropTests.m rename to src/objective-c/tests/InteropTests/InteropTests.m index aab38e3a594..164d571d125 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -36,6 +36,8 @@ #import #import +#import "InteropTestsBlockCallbacks.h" + #define TEST_TIMEOUT 32 extern const char *kCFStreamVarName; @@ -76,81 +78,6 @@ BOOL isRemoteInteropTest(NSString *host) { return [host isEqualToString:@"grpc-test.sandbox.googleapis.com"]; } -// Convenience class to use blocks as callbacks -@interface InteropTestsBlockCallbacks : NSObject - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback - writeMessageCallback:(void (^)(void))writeMessageCallback; - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; - -@end - -@implementation InteropTestsBlockCallbacks { - void (^_initialMetadataCallback)(NSDictionary *); - void (^_messageCallback)(id); - void (^_closeCallback)(NSDictionary *, NSError *); - void (^_writeMessageCallback)(void); - dispatch_queue_t _dispatchQueue; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback - writeMessageCallback:(void (^)(void))writeMessageCallback { - if ((self = [super init])) { - _initialMetadataCallback = initialMetadataCallback; - _messageCallback = messageCallback; - _closeCallback = closeCallback; - _writeMessageCallback = writeMessageCallback; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { - return [self initWithInitialMetadataCallback:initialMetadataCallback - messageCallback:messageCallback - closeCallback:closeCallback - writeMessageCallback:nil]; -} - -- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } -} - -- (void)didReceiveProtoMessage:(GPBMessage *)message { - if (_messageCallback) { - _messageCallback(message); - } -} - -- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } -} - -- (void)didWriteMessage { - if (_writeMessageCallback) { - _writeMessageCallback(); - } -} - -- (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; -} - -@end - #pragma mark Tests @implementation InteropTests { diff --git a/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.h b/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.h new file mode 100644 index 00000000000..fa0b8361b65 --- /dev/null +++ b/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.h @@ -0,0 +1,33 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +// Convenience class to use blocks as callbacks +@interface InteropTestsBlockCallbacks : NSObject + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback; + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; + +@end diff --git a/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.m b/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.m new file mode 100644 index 00000000000..1ab1fa995a6 --- /dev/null +++ b/src/objective-c/tests/InteropTests/InteropTestsBlockCallbacks.m @@ -0,0 +1,80 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "InteropTestsBlockCallbacks.h" + +@implementation InteropTestsBlockCallbacks { + void (^_initialMetadataCallback)(NSDictionary *); + void (^_messageCallback)(id); + void (^_closeCallback)(NSDictionary *, NSError *); + void (^_writeMessageCallback)(void); + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback + writeMessageCallback:(void (^)(void))writeMessageCallback { + if ((self = [super init])) { + _initialMetadataCallback = initialMetadataCallback; + _messageCallback = messageCallback; + _closeCallback = closeCallback; + _writeMessageCallback = writeMessageCallback; + _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback + messageCallback:(void (^)(id))messageCallback + closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { + return [self initWithInitialMetadataCallback:initialMetadataCallback + messageCallback:messageCallback + closeCallback:closeCallback + writeMessageCallback:nil]; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + if (_initialMetadataCallback) { + _initialMetadataCallback(initialMetadata); + } +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + if (_messageCallback) { + _messageCallback(message); + } +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { + if (_closeCallback) { + _closeCallback(trailingMetadata, error); + } +} + +- (void)didWriteMessage { + if (_writeMessageCallback) { + _writeMessageCallback(); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTests/InteropTestsLocalCleartext.m similarity index 100% rename from src/objective-c/tests/InteropTestsLocalCleartext.m rename to src/objective-c/tests/InteropTests/InteropTestsLocalCleartext.m diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTests/InteropTestsLocalSSL.m similarity index 100% rename from src/objective-c/tests/InteropTestsLocalSSL.m rename to src/objective-c/tests/InteropTests/InteropTestsLocalSSL.m diff --git a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m new file mode 100644 index 00000000000..c0beb107fad --- /dev/null +++ b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m @@ -0,0 +1,268 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#ifdef GRPC_COMPILE_WITH_CRONET +#import +#endif +#import +#import +#import +#import + +#import "InteropTestsBlockCallbacks.h" + +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); +static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); +static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); + +static const NSTimeInterval TEST_TIMEOUT = 8000; + +@interface RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize; +@end + +@implementation RMTStreamingOutputCallRequest (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize + requestedResponseSize:(NSNumber *)responseSize { + RMTStreamingOutputCallRequest *request = [self message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = responseSize.intValue; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return request; +} +@end + +@interface RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; +@end + +@implementation RMTStreamingOutputCallResponse (Constructors) ++ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { + RMTStreamingOutputCallResponse *response = [self message]; + response.payload.type = RMTPayloadType_Compressable; + response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; + return response; +} +@end + + + +@interface InteropTestsMultipleChannels : XCTestCase + +@end + +dispatch_once_t initCronet; + +@implementation InteropTestsMultipleChannels { + RMTTestService *_remoteService; + RMTTestService *_remoteCronetService; + RMTTestService *_localCleartextService; + RMTTestService *_localSSLService; +} + +- (void)setUp { + [super setUp]; + + self.continueAfterFailure = NO; + + _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:nil]; + + dispatch_once(&initCronet, ^{ + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + }); + + // Default stack with remote host + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeCronet; + // Cronet stack with remote host + _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:options]; + + + // Local stack with no SSL + options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeInsecure; + _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost callOptions:options]; + + // Local stack with SSL + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSString *certsPath = + [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; + NSError *error = nil; + NSString *certs = + [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; + XCTAssertNil(error); + + options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = GRPCTransportTypeChttp2BoringSSL; + options.PEMRootCertificates = certs; + options.hostNameOverride = @"foo.test.google.fr"; + _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost callOptions:options]; +} + +- (void)testEmptyUnaryRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + GPBEmpty *request = [GPBEmpty message]; + + void (^messageHandler)(id message) = ^(id message) { + id expectedResponse = [GPBEmpty message]; + XCTAssertEqualObjects(message, expectedResponse); + }; + + GRPCUnaryProtoCall *callRemote = [_remoteService emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callCronet = [_remoteCronetService emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectCronetRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callCleartext = [_localCleartextService emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectCleartext fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callSSL = [_localSSLService emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectSSL fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + [callRemote start]; + [callCronet start]; + [callCleartext start]; + [callSSL start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testFullDuplexRPC { + __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCronetRemote = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectCleartext = + [self expectationWithDescription:@"Remote RPC finish"]; + __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; + + NSArray *requestSizes = @[ @100, @101, @102, @103 ]; + NSArray *responseSizes = @[ @104, @105, @106, @107 ]; + XCTAssertEqual([requestSizes count], [responseSizes count]); + NSUInteger kRounds = [requestSizes count]; + NSMutableArray *calls = [NSMutableArray arrayWithCapacity:4]; + + NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; + NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; + for (int i = 0; i < kRounds; i++) { + requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] + requestedResponseSize:responseSizes[i]]; + responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; + } + + __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; + __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; + for (int i = 0; i < 4; i++) { + steps[i] = [NSNumber numberWithUnsignedInteger:0]; + requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; + [requestsBuffers[i] writeValue:requests[0]]; + } + + void (^handler)(NSUInteger index, id message) = ^(NSUInteger index, id message) { + NSUInteger step = [steps[index] unsignedIntegerValue]; + step++; + steps[index] = [NSNumber numberWithUnsignedInteger:step]; + if (step < kRounds) { + [calls[index] writeMessage:requests[step]]; + } else { + [calls[index] finish]; + } + }; + + calls[0] = [_remoteService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(0, message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectRemote fulfill]; + } writeMessageCallback:nil] + callOptions:nil]; + calls[1] = [_remoteCronetService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(1, message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectCronetRemote fulfill]; + } writeMessageCallback:nil] + callOptions:nil]; + calls[2] = [_localCleartextService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(2, message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectCleartext fulfill]; + } writeMessageCallback:nil] + callOptions:nil]; + calls[3] = [_localSSLService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(3, message); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error); + [expectSSL fulfill]; + } writeMessageCallback:nil] + callOptions:nil]; + for (int i = 0; i < 4; i++) { + [calls[i] start]; + [calls[i] writeMessage:requests[0]]; + } + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +@end diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTests/InteropTestsRemote.m similarity index 100% rename from src/objective-c/tests/InteropTestsRemote.m rename to src/objective-c/tests/InteropTests/InteropTestsRemote.m diff --git a/src/objective-c/tests/InteropTestsCallOptions/Info.plist b/src/objective-c/tests/InteropTestsCallOptions/Info.plist deleted file mode 100644 index 6c40a6cd0c4..00000000000 --- a/src/objective-c/tests/InteropTestsCallOptions/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m b/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m deleted file mode 100644 index db51cb1cfbb..00000000000 --- a/src/objective-c/tests/InteropTestsCallOptions/InteropTestsCallOptions.m +++ /dev/null @@ -1,116 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import - -#import -#import -#import -#import -#import -#import - -#define NSStringize_helper(x) #x -#define NSStringize(x) @NSStringize_helper(x) -static NSString *kRemoteHost = NSStringize(HOST_PORT_REMOTE); -const int32_t kRemoteInteropServerOverhead = 12; - -static const NSTimeInterval TEST_TIMEOUT = 16000; - -@interface InteropTestsCallOptions : XCTestCase - -@end - -@implementation InteropTestsCallOptions { - RMTTestService *_service; -} - -- (void)setUp { - self.continueAfterFailure = NO; - _service = [RMTTestService serviceWithHost:kRemoteHost]; - _service.options = [[GRPCCallOptions alloc] init]; -} - -- (void)test4MBResponsesAreAccepted { - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - const int32_t kPayloadSize = - 4 * 1024 * 1024 - kRemoteInteropServerOverhead; // 4MB - encoding overhead - request.responseSize = kPayloadSize; - - [_service unaryCallWithRequest:request - handler:^(RMTSimpleResponse *response, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", error); - XCTAssertEqual(response.payload.body.length, kPayloadSize); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testResponsesOverMaxSizeFailWithActionableMessage { - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - const int32_t kPayloadSize = - 4 * 1024 * 1024 - kRemoteInteropServerOverhead + 1; // 1B over max size - request.responseSize = kPayloadSize; - - [_service unaryCallWithRequest:request - handler:^(RMTSimpleResponse *response, NSError *error) { - XCTAssertEqualObjects( - error.localizedDescription, - @"Received message larger than max (4194305 vs. 4194304)"); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testResponsesOver4MBAreAcceptedIfOptedIn { - __weak XCTestExpectation *expectation = - [self expectationWithDescription:@"HigherResponseSizeLimit"]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB - request.responseSize = kPayloadSize; - - GRPCProtoCall *rpc = [_service - RPCToUnaryCallWithRequest:request - handler:^(RMTSimpleResponse *response, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", error); - XCTAssertEqual(response.payload.body.length, kPayloadSize); - [expectation fulfill]; - }]; - GRPCCallOptions *options = rpc.options; - options.responseSizeLimit = 6 * 1024 * 1024; - - [rpc start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testPerformanceExample { - // This is an example of a performance test case. - [self measureBlock:^{ - // Put the code you want to measure the time of here. - }]; -} - -@end diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist b/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist deleted file mode 100644 index 6c40a6cd0c4..00000000000 --- a/src/objective-c/tests/InteropTestsMultipleChannels/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m deleted file mode 100644 index b0d4e4883a3..00000000000 --- a/src/objective-c/tests/InteropTestsMultipleChannels/InteropTestsMultipleChannels.m +++ /dev/null @@ -1,259 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import - -#import -#import -#import -#import -#import - -#define NSStringize_helper(x) #x -#define NSStringize(x) @NSStringize_helper(x) -static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); -static NSString *const kLocalSSLHost = NSStringize(HOST_PORT_LOCALSSL); -static NSString *const kLocalCleartextHost = NSStringize(HOST_PORT_LOCAL); - -static const NSTimeInterval TEST_TIMEOUT = 8000; - -@interface RMTStreamingOutputCallRequest (Constructors) -+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize - requestedResponseSize:(NSNumber *)responseSize; -@end - -@implementation RMTStreamingOutputCallRequest (Constructors) -+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize - requestedResponseSize:(NSNumber *)responseSize { - RMTStreamingOutputCallRequest *request = [self message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = responseSize.intValue; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; - return request; -} -@end - -@interface RMTStreamingOutputCallResponse (Constructors) -+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize; -@end - -@implementation RMTStreamingOutputCallResponse (Constructors) -+ (instancetype)messageWithPayloadSize:(NSNumber *)payloadSize { - RMTStreamingOutputCallResponse *response = [self message]; - response.payload.type = RMTPayloadType_Compressable; - response.payload.body = [NSMutableData dataWithLength:payloadSize.unsignedIntegerValue]; - return response; -} -@end - -@interface InteropTestsMultipleChannels : XCTestCase - -@end - -dispatch_once_t initCronet; - -@implementation InteropTestsMultipleChannels { - RMTTestService *_remoteService; - RMTTestService *_remoteCronetService; - RMTTestService *_localCleartextService; - RMTTestService *_localSSLService; -} - -- (void)setUp { - [super setUp]; - - self.continueAfterFailure = NO; - - // Default stack with remote host - _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost]; - - // Cronet stack with remote host - _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost]; - - dispatch_once(&initCronet, ^{ - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - }); - - GRPCCallOptions *options = [[GRPCCallOptions alloc] init]; - options.transportType = GRPCTransportTypeCronet; - options.cronetEngine = [Cronet getGlobalEngine]; - _remoteCronetService.options = options; - - // Local stack with no SSL - _localCleartextService = [RMTTestService serviceWithHost:kLocalCleartextHost]; - options = [[GRPCCallOptions alloc] init]; - options.transportType = GRPCTransportTypeInsecure; - _localCleartextService.options = options; - - // Local stack with SSL - _localSSLService = [RMTTestService serviceWithHost:kLocalSSLHost]; - - NSBundle *bundle = [NSBundle bundleForClass:[self class]]; - NSString *certsPath = - [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; - NSError *error = nil; - NSString *certs = - [NSString stringWithContentsOfFile:certsPath encoding:NSUTF8StringEncoding error:&error]; - XCTAssertNil(error); - - options = [[GRPCCallOptions alloc] init]; - options.transportType = GRPCTransportTypeChttp2BoringSSL; - options.PEMRootCertificates = certs; - options.hostNameOverride = @"foo.test.google.fr"; - _localSSLService.options = options; -} - -- (void)testEmptyUnaryRPC { - __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectCronetRemote = - [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectCleartext = - [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; - - GPBEmpty *request = [GPBEmpty message]; - - void (^handler)(GPBEmpty *response, NSError *error) = ^(GPBEmpty *response, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", error); - - id expectedResponse = [GPBEmpty message]; - XCTAssertEqualObjects(response, expectedResponse); - }; - - [_remoteService emptyCallWithRequest:request - handler:^(GPBEmpty *response, NSError *error) { - handler(response, error); - [expectRemote fulfill]; - }]; - [_remoteCronetService emptyCallWithRequest:request - handler:^(GPBEmpty *response, NSError *error) { - handler(response, error); - [expectCronetRemote fulfill]; - }]; - [_localCleartextService emptyCallWithRequest:request - handler:^(GPBEmpty *response, NSError *error) { - handler(response, error); - [expectCleartext fulfill]; - }]; - [_localSSLService emptyCallWithRequest:request - handler:^(GPBEmpty *response, NSError *error) { - handler(response, error); - [expectSSL fulfill]; - }]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testFullDuplexRPC { - __weak XCTestExpectation *expectRemote = [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectCronetRemote = - [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectCleartext = - [self expectationWithDescription:@"Remote RPC finish"]; - __weak XCTestExpectation *expectSSL = [self expectationWithDescription:@"Remote RPC finish"]; - - NSArray *requestSizes = @[ @100, @101, @102, @103 ]; - NSArray *responseSizes = @[ @104, @105, @106, @107 ]; - XCTAssertEqual([requestSizes count], [responseSizes count]); - NSUInteger kRounds = [requestSizes count]; - - NSMutableArray *requests = [NSMutableArray arrayWithCapacity:kRounds]; - NSMutableArray *responses = [NSMutableArray arrayWithCapacity:kRounds]; - for (int i = 0; i < kRounds; i++) { - requests[i] = [RMTStreamingOutputCallRequest messageWithPayloadSize:requestSizes[i] - requestedResponseSize:responseSizes[i]]; - responses[i] = [RMTStreamingOutputCallResponse messageWithPayloadSize:responseSizes[i]]; - } - - __block NSMutableArray *steps = [NSMutableArray arrayWithCapacity:4]; - __block NSMutableArray *requestsBuffers = [NSMutableArray arrayWithCapacity:4]; - for (int i = 0; i < 4; i++) { - steps[i] = [NSNumber numberWithUnsignedInteger:0]; - requestsBuffers[i] = [[GRXBufferedPipe alloc] init]; - [requestsBuffers[i] writeValue:requests[0]]; - } - - BOOL (^handler)(int, BOOL, RMTStreamingOutputCallResponse *, NSError *) = - ^(int index, BOOL done, RMTStreamingOutputCallResponse *response, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", error); - XCTAssertTrue(done || response, @"Event handler called without an event."); - if (response) { - NSUInteger step = [steps[index] unsignedIntegerValue]; - XCTAssertLessThan(step, kRounds, @"More than %lu responses received.", - (unsigned long)kRounds); - XCTAssertEqualObjects(response, responses[step]); - step++; - steps[index] = [NSNumber numberWithUnsignedInteger:step]; - GRXBufferedPipe *pipe = requestsBuffers[index]; - if (step < kRounds) { - [pipe writeValue:requests[step]]; - } else { - [pipe writesFinishedWithError:nil]; - } - } - if (done) { - NSUInteger step = [steps[index] unsignedIntegerValue]; - XCTAssertEqual(step, kRounds, @"Received %lu responses instead of %lu.", step, kRounds); - return YES; - } - return NO; - }; - - [_remoteService - fullDuplexCallWithRequestsWriter:requestsBuffers[0] - eventHandler:^(BOOL done, - RMTStreamingOutputCallResponse *_Nullable response, - NSError *_Nullable error) { - if (handler(0, done, response, error)) { - [expectRemote fulfill]; - } - }]; - [_remoteCronetService - fullDuplexCallWithRequestsWriter:requestsBuffers[1] - eventHandler:^(BOOL done, - RMTStreamingOutputCallResponse *_Nullable response, - NSError *_Nullable error) { - if (handler(1, done, response, error)) { - [expectCronetRemote fulfill]; - } - }]; - [_localCleartextService - fullDuplexCallWithRequestsWriter:requestsBuffers[2] - eventHandler:^(BOOL done, - RMTStreamingOutputCallResponse *_Nullable response, - NSError *_Nullable error) { - if (handler(2, done, response, error)) { - [expectCleartext fulfill]; - } - }]; - [_localSSLService - fullDuplexCallWithRequestsWriter:requestsBuffers[3] - eventHandler:^(BOOL done, - RMTStreamingOutputCallResponse *_Nullable response, - NSError *_Nullable error) { - if (handler(3, done, response, error)) { - [expectSSL fulfill]; - } - }]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -@end diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist b/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist deleted file mode 100644 index ba72822e872..00000000000 --- a/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 34ed6680195..146abf5b0e0 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -5,23 +5,26 @@ install! 'cocoapods', :deterministic_uuids => false # Location of gRPC's repo root relative to this file. GRPC_LOCAL_SRC = '../../..' -# Install the dependencies in the main target plus all test targets. +target 'MacTests' do + platform :osx, '10.13' + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true + + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC + pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true + pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true +end + %w( - AllTests - RxLibraryUnitTests - InteropTestsRemote - InteropTestsLocalSSL - InteropTestsLocalCleartext - InteropTestsRemoteWithCronet - InteropTestsMultipleChannels - InteropTestsCallOptions UnitTests - InteropTestsRemoteCFStream - InteropTestsLocalSSLCFStream - InteropTestsLocalCleartextCFStream - APIv2Tests ).each do |target_name| - target target_name do + target target_name do platform :ios, '8.0' pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true @@ -35,52 +38,34 @@ GRPC_LOCAL_SRC = '../../..' pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - - if target_name == 'InteropTestsRemoteWithCronet' or target_name == 'InteropTestsMultipleChannels' - pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" - end end end -target 'MacTests' do - platform :osx, '10.13' - pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true - - pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - - pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - - pod 'gRPC', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC - pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true - pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true -end - %w( - CoreCronetEnd2EndTests - CronetUnitTests + InteropTests + CronetTests ).each do |target_name| target target_name do platform :ios, '8.0' - pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true + + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC + pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true + pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true + pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true end end -target 'ChannelTests' do - platform :ios, '8.0' - pod 'gRPC', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true -end - # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. @@ -127,7 +112,7 @@ post_install do |installer| # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void # function" warning config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1 GRPC_CFSTREAM=1' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' end end diff --git a/src/objective-c/tests/Tests.m b/src/objective-c/tests/Tests.m deleted file mode 100644 index 1d303497134..00000000000 --- a/src/objective-c/tests/Tests.m +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import - -@interface Tests : NSObject -@end - -@implementation Tests -@end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 27a617c83b4..1295731641b 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -7,186 +7,45 @@ objects = { /* Begin PBXBuildFile section */ - 06467F3A8D01EC493D12ADA2 /* libPods-CronetUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */; }; - 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */; }; - 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; }; - 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; - 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 48F1841C9A920626995DC28C /* libPods-ChannelTests.a */; }; - 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; - 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; - 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; - 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; - 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; - 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */; }; - 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; }; - 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; }; - 5EAD6D291E27047400002378 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */; }; - 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */; }; - 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */; }; - 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; - 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; - 5EC5E43C208185AD000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 5EC5E43D208185B0000EF4AD /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; - 5EC5E44C208185EC000EF4AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 5EC5E44D208185F0000EF4AD /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; - 5EC5E44E20818948000EF4AD /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; - 5EE84BF41D4717E40050C6CC /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; }; - 5EE84BF61D4717E40050C6CC /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 5EE84BFE1D471D400050C6CC /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; - 6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; - 63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; }; - 635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 63715F561B780C020029CB0B /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; - 6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; - 6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; - 6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; - 63DC84181BE15179000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; }; - 63DC84281BE15267000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; }; - 63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; - 63DC84391BE15294000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 63DC84481BE152B5000708E8 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; - 63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; - 63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; - 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; - 63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; - 63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; - 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AF3FC2CFFE7B0961823BC740 /* libPods-InteropTestsCallOptions.a */; }; - 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 355D0E30AD224763BC9519F4 /* libPods-InteropTestsMultipleChannels.a */; }; - 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; + 5E0282E9215AA697007AC99D /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; }; + 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; + 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; + 5E3F14862278BFFF007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; + 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; }; + 5E7F486522775B41006656AD /* CronetUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.mm */; }; + 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */; }; + 5E7F487922778226006656AD /* InteropTestsMultipleChannels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487722778226006656AD /* InteropTestsMultipleChannels.m */; }; + 5E7F487D22778256006656AD /* ChannelPoolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487B22778256006656AD /* ChannelPoolTest.m */; }; + 5E7F487E22778256006656AD /* ChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487C22778256006656AD /* ChannelTests.m */; }; + 5E7F4880227782C1006656AD /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487F227782C1006656AD /* APIv2Tests.m */; }; + 5E7F488322778A88006656AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488222778A88006656AD /* InteropTests.m */; }; + 5E7F488422778A88006656AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488222778A88006656AD /* InteropTests.m */; }; + 5E7F488522778A88006656AD /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488222778A88006656AD /* InteropTests.m */; }; + 5E7F488722778AEA006656AD /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488622778AEA006656AD /* GRPCClientTests.m */; }; + 5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488822778B04006656AD /* InteropTestsRemote.m */; }; + 5E7F488B22778B5D006656AD /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488A22778B5D006656AD /* RxLibraryUnitTests.m */; }; + 5E7F488C22778C60006656AD /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F487F227782C1006656AD /* APIv2Tests.m */; }; + 5E7F488D22778C85006656AD /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; + 5E7F488E22778C87006656AD /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; + 5E7F488F22778C8C006656AD /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488822778B04006656AD /* InteropTestsRemote.m */; }; + 5E7F489022778C95006656AD /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F488A22778B5D006656AD /* RxLibraryUnitTests.m */; }; + 5EA4770322736178000F72FC /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; + 5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; + 5EA4770522736AC4000F72FC /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; + 65EB19E418B39A8374D407BB /* libPods-CronetTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B1511C20E16A8422B58D61A /* libPods-CronetTests.a */; }; + 903163C7FE885838580AEC7A /* libPods-InteropTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D457AD9797664CFA191C3280 /* libPods-InteropTests.a */; }; 953CD2942A3A6D6CE695BE87 /* libPods-MacTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 276873A05AC5479B60DF6079 /* libPods-MacTests.a */; }; - 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */; }; B071230B22669EED004B64A1 /* StressTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B071230A22669EED004B64A1 /* StressTests.m */; }; - B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */; }; - B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */; }; - B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; }; - B0BB3F05225E7A9F008DA580 /* InteropTestsRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */; }; - B0BB3F06225E7AAD008DA580 /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; - B0BB3F07225E7AB5008DA580 /* APIv2Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */; }; - B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; + B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */; }; B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */; }; - B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B992266F3CB00A4078D /* StressTestsSSL.m */; }; B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */ = {isa = PBXBuildFile; fileRef = B0D39B9B2266FF9800A4078D /* StressTestsCleartext.m */; }; - BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; - C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; - F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5EAD6D2A1E27047400002378 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 63DC84191BE15179000708E8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 63DC84291BE15267000708E8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 63DC843A1BE15294000708E8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; - 63DC84491BE152B5000708E8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 635697BF1B14FC11007A7283 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 635697C61B14FC11007A7283; - remoteInfo = Tests; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 635697C51B14FC11007A7283 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 02192CF1FF9534E3D18C65FC /* Pods-CronetUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.release.xcconfig"; sourceTree = ""; }; + 070266E2626EB997B54880A3 /* Pods-InteropTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTests/Pods-InteropTests.test.xcconfig"; sourceTree = ""; }; 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = ""; }; 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartextCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -198,9 +57,11 @@ 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 16A2E4C5839C83FBDA63881F /* Pods-MacTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.cronet.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; + 1B1511C20E16A8422B58D61A /* libPods-CronetTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 1E43EAE443CBB4482B1EB071 /* Pods-MacTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.release.xcconfig"; sourceTree = ""; }; 1F5E788FBF9A4A06EB9E1ACD /* Pods-MacTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-MacTests/Pods-MacTests.test.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 20F6A3D59D0EE091E2D43953 /* Pods-CronetTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CronetTests/Pods-CronetTests.cronet.xcconfig"; sourceTree = ""; }; 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.release.xcconfig"; sourceTree = ""; }; 276873A05AC5479B60DF6079 /* libPods-MacTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MacTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -226,58 +87,41 @@ 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; + 5AB9A82F289D548D6B8816F9 /* Pods-CronetTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CronetTests/Pods-CronetTests.test.xcconfig"; sourceTree = ""; }; 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; - 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = APIv2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; - 5E3B95A621CAC6C500C0A151 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsCallOptions.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsCallOptions.m; sourceTree = ""; }; - 5E7D71B6210B9EC9001EA6BA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; + 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSErrorUnitTests.m; sourceTree = ""; }; + 5E3F14822278B42D007C6D90 /* InteropTestsBlockCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InteropTestsBlockCallbacks.h; sourceTree = ""; }; + 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsBlockCallbacks.m; sourceTree = ""; }; + 5E7F485922775B15006656AD /* CronetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E7F486622776AD8006656AD /* Cronet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cronet.framework; path = Pods/CronetFramework/Cronet.framework; sourceTree = ""; }; + 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; + 5E7F487722778226006656AD /* InteropTestsMultipleChannels.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsMultipleChannels.m; sourceTree = ""; }; + 5E7F487B22778256006656AD /* ChannelPoolTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChannelPoolTest.m; sourceTree = ""; }; + 5E7F487C22778256006656AD /* ChannelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChannelTests.m; sourceTree = ""; }; + 5E7F487F227782C1006656AD /* APIv2Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APIv2Tests.m; sourceTree = ""; }; + 5E7F488122778A88006656AD /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = ""; }; + 5E7F488222778A88006656AD /* InteropTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTests.m; sourceTree = ""; }; + 5E7F488622778AEA006656AD /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; + 5E7F488822778B04006656AD /* InteropTestsRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemote.m; sourceTree = ""; }; + 5E7F488A22778B5D006656AD /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; + 5EA476F42272816A000F72FC /* InteropTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = ""; }; - 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EAD6D261E27047400002378 /* CronetUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CronetUnitTests.m; sourceTree = ""; }; - 5EAD6D281E27047400002378 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5EAD6D261E27047400002378 /* CronetUnitTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = CronetUnitTests.mm; path = CronetTests/CronetUnitTests.mm; sourceTree = SOURCE_ROOT; }; 5EAFE8271F8EFB87007F2189 /* version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = version.h; sourceTree = ""; }; - 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChannelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelTests.m; sourceTree = ""; }; - 5EB2A2E82107DED300EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsMultipleChannels.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsMultipleChannels.m; sourceTree = ""; }; - 5EB2A2F92109284500EB4B69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ChannelPoolTest.m; sourceTree = ""; }; - 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartextCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSLCFStream.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteWithCronet.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemoteWithCronet.m; sourceTree = ""; }; - 5EE84BF51D4717E40050C6CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; - 63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; - 635697C71B14FC11007A7283 /* libTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTests.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 635697CC1B14FC11007A7283 /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; + 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = InteropTestsRemoteWithCronet.m; path = CronetTests/InteropTestsRemoteWithCronet.m; sourceTree = SOURCE_ROOT; }; 635697D81B14FC11007A7283 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTests.m; sourceTree = ""; }; - 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalCleartext.m; sourceTree = ""; }; - 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemote.m; sourceTree = ""; }; - 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxLibraryUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemote.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalSSL.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsLocalCleartext.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 63E240CC1B6C4D3A005F3B0E /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = ""; }; - 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = ""; }; + 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = InteropTestsLocalCleartext.m; path = InteropTests/InteropTestsLocalCleartext.m; sourceTree = SOURCE_ROOT; }; + 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = InteropTestsLocalSSL.m; path = InteropTests/InteropTestsLocalSSL.m; sourceTree = SOURCE_ROOT; }; 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; 64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests.debug.xcconfig"; sourceTree = ""; }; 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.test.xcconfig"; sourceTree = ""; }; + 680439AC2BC8761EDD54A1EA /* Pods-InteropTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTests/Pods-InteropTests.debug.xcconfig"; sourceTree = ""; }; 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.cronet.xcconfig"; sourceTree = ""; }; 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.test.xcconfig"; sourceTree = ""; }; 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; + 7F4F42EBAF311E9F84FCA32E /* Pods-CronetTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CronetTests/Pods-CronetTests.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-APIv2Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests.cronet.xcconfig"; sourceTree = ""; }; 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.cronet.xcconfig"; sourceTree = ""; }; @@ -305,7 +149,9 @@ C6134277D2EB8B380862A03F /* libPods-CronetUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CronetUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsCallOptions.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions.release.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CDF6CC70B8BF9D10EFE7D199 /* Pods-InteropTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTests/Pods-InteropTests.cronet.xcconfig"; sourceTree = ""; }; D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.test.xcconfig"; sourceTree = ""; }; + D457AD9797664CFA191C3280 /* libPods-InteropTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.release.xcconfig"; sourceTree = ""; }; DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.test.xcconfig"; sourceTree = ""; }; DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -319,8 +165,10 @@ E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsMultipleChannels.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels.test.xcconfig"; sourceTree = ""; }; EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; }; + EC66920112123D2DB1CB7F6C /* Pods-CronetTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CronetTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CronetTests/Pods-CronetTests.debug.xcconfig"; sourceTree = ""; }; F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F6A7EECACBB4849DDD3F450A /* Pods-InteropTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTests/Pods-InteropTests.release.xcconfig"; sourceTree = ""; }; F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChannelTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests.debug.xcconfig"; sourceTree = ""; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -332,146 +180,23 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */, CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5E3B959F21CAC6C500C0A151 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 98478C9F42329DF769A45B6C /* libPods-APIv2Tests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E7D71AF210B9EC8001EA6BA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E7D71B7210B9EC9001EA6BA /* libTests.a in Frameworks */, - 6C1A3F81CCF7C998B4813EFD /* libPods-InteropTestsCallOptions.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */, - 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EAD6D211E27047400002378 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EAD6D291E27047400002378 /* libTests.a in Frameworks */, - 06467F3A8D01EC493D12ADA2 /* libPods-CronetUnitTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EB2A2E12107DED300EB4B69 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EB2A2E92107DED300EB4B69 /* libTests.a in Frameworks */, - 1A0FB7F8C95A2F82538BC950 /* libPods-ChannelTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EB2A2F22109284500EB4B69 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EB2A2FA2109284500EB4B69 /* libTests.a in Frameworks */, - 886717A79EFF774F356798E6 /* libPods-InteropTestsMultipleChannels.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E41E208177CC000EF4AD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E42E2081856B000EF4AD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E43F208185CE000EF4AD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EE84BEE1D4717E40050C6CC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EE84BF61D4717E40050C6CC /* libTests.a in Frameworks */, - 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63423F411B150A5F006CF63C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */, - F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 635697C41B14FC11007A7283 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84101BE15179000708E8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC84181BE15179000708E8 /* libTests.a in Frameworks */, - 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84201BE15267000708E8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC84281BE15267000708E8 /* libTests.a in Frameworks */, - 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84311BE15294000708E8 /* Frameworks */ = { + 5E7F485622775B15006656AD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 63DC84391BE15294000708E8 /* libTests.a in Frameworks */, - 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */, + 65EB19E418B39A8374D407BB /* libPods-CronetTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 63DC84401BE152B5000708E8 /* Frameworks */ = { + 5EA476F12272816A000F72FC /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 63DC84481BE152B5000708E8 /* libTests.a in Frameworks */, - 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */, + 903163C7FE885838580AEC7A /* libPods-InteropTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -489,6 +214,7 @@ 136D535E19727099B941D7B1 /* Frameworks */ = { isa = PBXGroup; children = ( + 5E7F486622776AD8006656AD /* Cronet.framework */, 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */, CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */, FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */, @@ -508,6 +234,8 @@ 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, B6AD69CACF67505B0F028E92 /* libPods-APIv2Tests.a */, 276873A05AC5479B60DF6079 /* libPods-MacTests.a */, + D457AD9797664CFA191C3280 /* libPods-InteropTests.a */, + 1B1511C20E16A8422B58D61A /* libPods-CronetTests.a */, ); name = Frameworks; sourceTree = ""; @@ -585,6 +313,14 @@ 1F5E788FBF9A4A06EB9E1ACD /* Pods-MacTests.test.xcconfig */, 16A2E4C5839C83FBDA63881F /* Pods-MacTests.cronet.xcconfig */, 1E43EAE443CBB4482B1EB071 /* Pods-MacTests.release.xcconfig */, + 680439AC2BC8761EDD54A1EA /* Pods-InteropTests.debug.xcconfig */, + 070266E2626EB997B54880A3 /* Pods-InteropTests.test.xcconfig */, + CDF6CC70B8BF9D10EFE7D199 /* Pods-InteropTests.cronet.xcconfig */, + F6A7EECACBB4849DDD3F450A /* Pods-InteropTests.release.xcconfig */, + EC66920112123D2DB1CB7F6C /* Pods-CronetTests.debug.xcconfig */, + 5AB9A82F289D548D6B8816F9 /* Pods-CronetTests.test.xcconfig */, + 20F6A3D59D0EE091E2D43953 /* Pods-CronetTests.cronet.xcconfig */, + 7F4F42EBAF311E9F84FCA32E /* Pods-CronetTests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -592,89 +328,50 @@ 5E0282E7215AA697007AC99D /* UnitTests */ = { isa = PBXGroup; children = ( - 5E0282E8215AA697007AC99D /* UnitTests.m */, - 5E0282EA215AA697007AC99D /* Info.plist */, + 5E7F488A22778B5D006656AD /* RxLibraryUnitTests.m */, + 5E7F488622778AEA006656AD /* GRPCClientTests.m */, + 5E7F487F227782C1006656AD /* APIv2Tests.m */, + 5E7F487B22778256006656AD /* ChannelPoolTest.m */, + 5E7F487C22778256006656AD /* ChannelTests.m */, + 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */, ); path = UnitTests; sourceTree = ""; }; - 5E3B95A321CAC6C500C0A151 /* APIv2Tests */ = { - isa = PBXGroup; - children = ( - 5E3B95A421CAC6C500C0A151 /* APIv2Tests.m */, - 5E3B95A621CAC6C500C0A151 /* Info.plist */, - ); - path = APIv2Tests; - sourceTree = ""; - }; - 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */ = { - isa = PBXGroup; - children = ( - 5E7D71B4210B9EC9001EA6BA /* InteropTestsCallOptions.m */, - 5E7D71B6210B9EC9001EA6BA /* Info.plist */, - ); - path = InteropTestsCallOptions; - sourceTree = ""; - }; - 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { - isa = PBXGroup; - children = ( - 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */, - ); - path = CoreCronetEnd2EndTests; - sourceTree = ""; - }; - 5EAD6D251E27047400002378 /* CronetUnitTests */ = { - isa = PBXGroup; - children = ( - 5EAD6D261E27047400002378 /* CronetUnitTests.m */, - 5EAD6D281E27047400002378 /* Info.plist */, - ); - path = CronetUnitTests; - sourceTree = ""; - }; - 5EB2A2E52107DED300EB4B69 /* ChannelTests */ = { - isa = PBXGroup; - children = ( - 5EB5C3A921656CEA00ADC300 /* ChannelPoolTest.m */, - 5EB2A2E62107DED300EB4B69 /* ChannelTests.m */, - 5EB2A2E82107DED300EB4B69 /* Info.plist */, - ); - path = ChannelTests; - sourceTree = ""; - }; - 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */ = { + 5E7F485A22775B15006656AD /* CronetTests */ = { isa = PBXGroup; children = ( - 5EB2A2F72109284500EB4B69 /* InteropTestsMultipleChannels.m */, - 5EB2A2F92109284500EB4B69 /* Info.plist */, + 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */, + 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */, + 5EAD6D261E27047400002378 /* CronetUnitTests.mm */, ); - path = InteropTestsMultipleChannels; + path = CronetTests; sourceTree = ""; }; - 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { + 5E7F48762277820F006656AD /* InteropTests */ = { isa = PBXGroup; children = ( - 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */, - 5EE84BF51D4717E40050C6CC /* Info.plist */, + 5E7F488822778B04006656AD /* InteropTestsRemote.m */, + 5E7F488122778A88006656AD /* InteropTests.h */, + 5E7F488222778A88006656AD /* InteropTests.m */, + 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */, + 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */, + 5E7F487722778226006656AD /* InteropTestsMultipleChannels.m */, + 5E3F14822278B42D007C6D90 /* InteropTestsBlockCallbacks.h */, + 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */, ); - path = InteropTestsRemoteWithCronet; + path = InteropTests; sourceTree = ""; }; 635697BE1B14FC11007A7283 = { isa = PBXGroup; children = ( + 5E7F48762277820F006656AD /* InteropTests */, 635697C91B14FC11007A7283 /* Tests */, 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */, - 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, - 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, - 5EAD6D251E27047400002378 /* CronetUnitTests */, - 5EB2A2E52107DED300EB4B69 /* ChannelTests */, - 5EB2A2F62109284500EB4B69 /* InteropTestsMultipleChannels */, - 5E7D71B3210B9EC9001EA6BA /* InteropTestsCallOptions */, 5E0282E7215AA697007AC99D /* UnitTests */, - 5E3B95A321CAC6C500C0A151 /* APIv2Tests */, B0BB3EF8225E795F008DA580 /* MacTests */, + 5E7F485A22775B15006656AD /* CronetTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -684,24 +381,10 @@ 635697C81B14FC11007A7283 /* Products */ = { isa = PBXGroup; children = ( - 635697C71B14FC11007A7283 /* libTests.a */, - 63423F441B150A5F006CF63C /* AllTests.xctest */, - 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */, - 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */, - 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */, - 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */, - 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */, - 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */, - 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */, - 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */, - 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */, - 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */, - 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */, - 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */, - 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */, 5E0282E6215AA697007AC99D /* UnitTests.xctest */, - 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */, B0BB3EF7225E795F008DA580 /* MacTests.xctest */, + 5EA476F42272816A000F72FC /* InteropTests.xctest */, + 5E7F485922775B15006656AD /* CronetTests.xctest */, ); name = Products; sourceTree = ""; @@ -710,14 +393,6 @@ isa = PBXGroup; children = ( 5EAFE8271F8EFB87007F2189 /* version.h */, - 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */, - 63E240CC1B6C4D3A005F3B0E /* InteropTests.h */, - 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */, - 6379CC4F1BE16703001BC0A1 /* InteropTestsRemote.m */, - 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */, - 63715F551B780C020029CB0B /* InteropTestsLocalCleartext.m */, - 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */, - 635697CC1B14FC11007A7283 /* Tests.m */, 635697D71B14FC11007A7283 /* Supporting Files */, ); name = Tests; @@ -759,769 +434,348 @@ buildRules = ( ); dependencies = ( - 5E0282ED215AA697007AC99D /* PBXTargetDependency */, ); name = UnitTests; productName = UnitTests; productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5E3B95A121CAC6C500C0A151 /* APIv2Tests */ = { + 5E7F485822775B15006656AD /* CronetTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */; + buildConfigurationList = 5E7F485E22775B15006656AD /* Build configuration list for PBXNativeTarget "CronetTests" */; buildPhases = ( - EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */, - 5E3B959E21CAC6C500C0A151 /* Sources */, - 5E3B959F21CAC6C500C0A151 /* Frameworks */, - 5E3B95A021CAC6C500C0A151 /* Resources */, - C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */, + CCAEC0F23E05489651A07D53 /* [CP] Check Pods Manifest.lock */, + 5E7F485522775B15006656AD /* Sources */, + 5E7F485622775B15006656AD /* Frameworks */, + 5E7F485722775B15006656AD /* Resources */, + 292EA42A76AC7933A37235FD /* [CP] Embed Pods Frameworks */, + 30AFD6F6FC40B9923632A866 /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); - name = APIv2Tests; - productName = APIv2Tests; - productReference = 5E3B95A221CAC6C500C0A151 /* APIv2Tests.xctest */; + name = CronetTests; + productName = CronetTests; + productReference = 5E7F485922775B15006656AD /* CronetTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */ = { + 5EA476F32272816A000F72FC /* InteropTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */; + buildConfigurationList = 5EA477002272816B000F72FC /* Build configuration list for PBXNativeTarget "InteropTests" */; buildPhases = ( - 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */, - 5E7D71AE210B9EC8001EA6BA /* Sources */, - 5E7D71AF210B9EC8001EA6BA /* Frameworks */, - 5E7D71B0210B9EC8001EA6BA /* Resources */, - 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */, + 40BCDB09674DF988C708D22B /* [CP] Check Pods Manifest.lock */, + 5EA476F02272816A000F72FC /* Sources */, + 5EA476F12272816A000F72FC /* Frameworks */, + 5EA476F22272816A000F72FC /* Resources */, + D11CB94CF56A1E53760D29D8 /* [CP] Copy Pods Resources */, + 0FEFD5FC6B323AC95549AE4A /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( - 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */, ); - name = InteropTestsCallOptions; - productName = InteropTestsCallOptions; - productReference = 5E7D71B2210B9EC8001EA6BA /* InteropTestsCallOptions.xctest */; + name = InteropTests; + productName = InteropTests; + productReference = 5EA476F42272816A000F72FC /* InteropTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { + B0BB3EF6225E795F008DA580 /* MacTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; + buildConfigurationList = B0BB3EFC225E795F008DA580 /* Build configuration list for PBXNativeTarget "MacTests" */; buildPhases = ( - F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */, - 5E8A5DA01D3840B4000F8BC4 /* Sources */, - 5E8A5DA11D3840B4000F8BC4 /* Frameworks */, - 5E8A5DA21D3840B4000F8BC4 /* Resources */, - E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */, + E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */, + B0BB3EF3225E795F008DA580 /* Sources */, + B0BB3EF4225E795F008DA580 /* Frameworks */, + B0BB3EF5225E795F008DA580 /* Resources */, + 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( - 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */, ); - name = CoreCronetEnd2EndTests; - productName = CoreCronetEnd2EndTests; - productReference = 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */; + name = MacTests; + productName = MacTests; + productReference = B0BB3EF7225E795F008DA580 /* MacTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 5EAD6D231E27047400002378 /* CronetUnitTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EAD6D2F1E27047400002378 /* Build configuration list for PBXNativeTarget "CronetUnitTests" */; - buildPhases = ( - 80E2DDD2EC04A4009F45E933 /* [CP] Check Pods Manifest.lock */, - 5EAD6D201E27047400002378 /* Sources */, - 5EAD6D211E27047400002378 /* Frameworks */, - 5EAD6D221E27047400002378 /* Resources */, - A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 635697BF1B14FC11007A7283 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0630; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5E0282E5215AA697007AC99D = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + 5E7F485822775B15006656AD = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + 5EA476F32272816A000F72FC = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + B0BB3EF6225E795F008DA580 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, ); - dependencies = ( - 5EAD6D2B1E27047400002378 /* PBXTargetDependency */, + mainGroup = 635697BE1B14FC11007A7283; + productRefGroup = 635697C81B14FC11007A7283 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5E0282E5215AA697007AC99D /* UnitTests */, + B0BB3EF6225E795F008DA580 /* MacTests */, + 5EA476F32272816A000F72FC /* InteropTests */, + 5E7F485822775B15006656AD /* CronetTests */, ); - name = CronetUnitTests; - productName = CronetUnitTests; - productReference = 5EAD6D241E27047400002378 /* CronetUnitTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; }; - 5EB2A2E32107DED300EB4B69 /* ChannelTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */; - buildPhases = ( - 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */, - 5EB2A2E02107DED300EB4B69 /* Sources */, - 5EB2A2E12107DED300EB4B69 /* Frameworks */, - 5EB2A2E22107DED300EB4B69 /* Resources */, - 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */, +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5E0282E4215AA697007AC99D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ); - buildRules = ( + runOnlyForDeploymentPostprocessing = 0; + }; + 5E7F485722775B15006656AD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( - 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */, + runOnlyForDeploymentPostprocessing = 0; + }; + 5EA476F22272816A000F72FC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EA4770522736AC4000F72FC /* TestCertificates.bundle in Resources */, ); - name = ChannelTests; - productName = ChannelTests; - productReference = 5EB2A2E42107DED300EB4B69 /* ChannelTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; }; - 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */; - buildPhases = ( - 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */, - 5EB2A2F12109284500EB4B69 /* Sources */, - 5EB2A2F22109284500EB4B69 /* Frameworks */, - 5EB2A2F32109284500EB4B69 /* Resources */, - 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */, - 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */, + B0BB3EF5225E795F008DA580 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */, ); - buildRules = ( + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0FEFD5FC6B323AC95549AE4A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( - 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */, + inputFileListPaths = ( ); - name = InteropTestsMultipleChannels; - productName = InteropTestsMultipleChannels; - productReference = 5EB2A2F52109284500EB4B69 /* InteropTestsMultipleChannels.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */; - buildPhases = ( - 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */, - 5EC5E41D208177CC000EF4AD /* Sources */, - 5EC5E41E208177CC000EF4AD /* Frameworks */, - 5EC5E41F208177CC000EF4AD /* Resources */, - 95FBC48B743503845678584F /* [CP] Copy Pods Resources */, + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", ); - buildRules = ( + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( ); - dependencies = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); - name = InteropTestsRemoteCFStream; - productName = InteropTestsRemoteCFStream; - productReference = 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EC5E4362081856C000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartextCFStream" */; - buildPhases = ( - 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */, - 5EC5E42D2081856B000EF4AD /* Sources */, - 5EC5E42E2081856B000EF4AD /* Frameworks */, - 5EC5E42F2081856B000EF4AD /* Resources */, - A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */, + 292EA42A76AC7933A37235FD /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - buildRules = ( + inputFileListPaths = ( ); - dependencies = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-frameworks.sh", + "${PODS_ROOT}/CronetFramework/Cronet.framework", ); - name = InteropTestsLocalCleartextCFStream; - productName = InteropTestsLocalCleartextCFStream; - productReference = 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EC5E447208185CE000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSLCFStream" */; - buildPhases = ( - F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */, - 5EC5E43E208185CE000EF4AD /* Sources */, - 5EC5E43F208185CE000EF4AD /* Frameworks */, - 5EC5E440208185CE000EF4AD /* Resources */, - 4EB2FFF40BB00AD0C545D7EF /* [CP] Copy Pods Resources */, - ); - buildRules = ( + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( ); - dependencies = ( + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); - name = InteropTestsLocalSSLCFStream; - productName = InteropTestsLocalSSLCFStream; - productReference = 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - 5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */; - buildPhases = ( - C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */, - 5EE84BED1D4717E40050C6CC /* Sources */, - 5EE84BEE1D4717E40050C6CC /* Frameworks */, - 5EE84BEF1D4717E40050C6CC /* Resources */, - 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */, - DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */, - ); - buildRules = ( + 30AFD6F6FC40B9923632A866 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( - 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */, + inputFileListPaths = ( ); - name = InteropTestsRemoteWithCronet; - productName = InteropTestsRemoteWithCronet; - productReference = 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 63423F431B150A5F006CF63C /* AllTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */; - buildPhases = ( - 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */, - 63423F401B150A5F006CF63C /* Sources */, - 63423F411B150A5F006CF63C /* Frameworks */, - 63423F421B150A5F006CF63C /* Resources */, - A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */, + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); - buildRules = ( + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( ); - dependencies = ( - 63423F4C1B150A5F006CF63C /* PBXTargetDependency */, + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); - name = AllTests; - productName = AllTests; - productReference = 63423F441B150A5F006CF63C /* AllTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-resources.sh\"\n"; + showEnvVarsInLog = 0; }; - 635697C61B14FC11007A7283 /* Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */; - buildPhases = ( - 635697C31B14FC11007A7283 /* Sources */, - 635697C41B14FC11007A7283 /* Frameworks */, - 635697C51B14FC11007A7283 /* CopyFiles */, - ); - buildRules = ( + 40BCDB09674DF988C708D22B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( + inputFileListPaths = ( ); - name = Tests; - productName = Tests; - productReference = 635697C71B14FC11007A7283 /* libTests.a */; - productType = "com.apple.product-type.library.static"; - }; - 63DC84121BE15179000708E8 /* RxLibraryUnitTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */; - buildPhases = ( - B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */, - 63DC840F1BE15179000708E8 /* Sources */, - 63DC84101BE15179000708E8 /* Frameworks */, - 63DC84111BE15179000708E8 /* Resources */, - C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */, + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - buildRules = ( + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - dependencies = ( - 63DC841A1BE15179000708E8 /* PBXTargetDependency */, + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-InteropTests-checkManifestLockResult.txt", ); - name = RxLibraryUnitTests; - productName = RxLibraryUnitTests; - productReference = 63DC84131BE15179000708E8 /* RxLibraryUnitTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 63DC84221BE15267000708E8 /* InteropTestsRemote */ = { - isa = PBXNativeTarget; - buildConfigurationList = 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */; - buildPhases = ( - 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */, - 63DC841F1BE15267000708E8 /* Sources */, - 63DC84201BE15267000708E8 /* Frameworks */, - 63DC84211BE15267000708E8 /* Resources */, - C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */, - ); - buildRules = ( + 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( - 63DC842A1BE15267000708E8 /* PBXTargetDependency */, + inputFileListPaths = ( ); - name = InteropTestsRemote; - productName = InteropTests; - productReference = 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */ = { - isa = PBXNativeTarget; - buildConfigurationList = 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */; - buildPhases = ( - 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */, - 63DC84301BE15294000708E8 /* Sources */, - 63DC84311BE15294000708E8 /* Frameworks */, - 63DC84321BE15294000708E8 /* Resources */, - 693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */, + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-macOS/gRPCCertificates.bundle", ); - buildRules = ( + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( ); - dependencies = ( - 63DC843B1BE15294000708E8 /* PBXTargetDependency */, + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); - name = InteropTestsLocalSSL; - productName = InteropTestsLocalSSL; - productReference = 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh\"\n"; + showEnvVarsInLog = 0; }; - 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */ = { - isa = PBXNativeTarget; - buildConfigurationList = 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */; - buildPhases = ( - 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */, - 63DC843F1BE152B5000708E8 /* Sources */, - 63DC84401BE152B5000708E8 /* Frameworks */, - 63DC84411BE152B5000708E8 /* Resources */, - 8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */, + 9AD0B5E94F2AA5962EA6AA36 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - buildRules = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); - dependencies = ( - 63DC844A1BE152B5000708E8 /* PBXTargetDependency */, + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); - name = InteropTestsLocalCleartext; - productName = InteropTestsLocalCleartext; - productReference = 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n"; + showEnvVarsInLog = 0; }; - B0BB3EF6225E795F008DA580 /* MacTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = B0BB3EFC225E795F008DA580 /* Build configuration list for PBXNativeTarget "MacTests" */; - buildPhases = ( - E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */, - B0BB3EF3225E795F008DA580 /* Sources */, - B0BB3EF4225E795F008DA580 /* Frameworks */, - B0BB3EF5225E795F008DA580 /* Resources */, - 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */, - ); - buildRules = ( + CCAEC0F23E05489651A07D53 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( ); - dependencies = ( + inputFileListPaths = ( ); - name = MacTests; - productName = MacTests; - productReference = B0BB3EF7225E795F008DA580 /* MacTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 635697BF1B14FC11007A7283 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0630; - ORGANIZATIONNAME = gRPC; - TargetAttributes = { - 5E0282E5215AA697007AC99D = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; - 5E3B95A121CAC6C500C0A151 = { - CreatedOnToolsVersion = 10.0; - ProvisioningStyle = Automatic; - }; - 5E7D71B1210B9EC8001EA6BA = { - CreatedOnToolsVersion = 9.3; - ProvisioningStyle = Automatic; - }; - 5E8A5DA31D3840B4000F8BC4 = { - CreatedOnToolsVersion = 7.3.1; - }; - 5EAD6D231E27047400002378 = { - CreatedOnToolsVersion = 7.3.1; - }; - 5EB2A2E32107DED300EB4B69 = { - CreatedOnToolsVersion = 9.3; - ProvisioningStyle = Automatic; - }; - 5EB2A2F42109284500EB4B69 = { - CreatedOnToolsVersion = 9.3; - ProvisioningStyle = Automatic; - }; - 5EC5E420208177CC000EF4AD = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; - 5EC5E4302081856B000EF4AD = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; - 5EC5E441208185CE000EF4AD = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; - 5EE84BF01D4717E40050C6CC = { - CreatedOnToolsVersion = 7.3.1; - }; - 63423F431B150A5F006CF63C = { - CreatedOnToolsVersion = 6.3.1; - }; - 635697C61B14FC11007A7283 = { - CreatedOnToolsVersion = 6.3.1; - }; - 63DC84121BE15179000708E8 = { - CreatedOnToolsVersion = 7.0.1; - }; - 63DC84221BE15267000708E8 = { - CreatedOnToolsVersion = 7.0.1; - }; - 63DC84331BE15294000708E8 = { - CreatedOnToolsVersion = 7.0.1; - }; - 63DC84421BE152B5000708E8 = { - CreatedOnToolsVersion = 7.0.1; - }; - B0BB3EF6225E795F008DA580 = { - CreatedOnToolsVersion = 10.1; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - mainGroup = 635697BE1B14FC11007A7283; - productRefGroup = 635697C81B14FC11007A7283 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 635697C61B14FC11007A7283 /* Tests */, - 63423F431B150A5F006CF63C /* AllTests */, - 63DC84121BE15179000708E8 /* RxLibraryUnitTests */, - 63DC84221BE15267000708E8 /* InteropTestsRemote */, - 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */, - 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */, - 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, - 5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */, - 5EAD6D231E27047400002378 /* CronetUnitTests */, - 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */, - 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */, - 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */, - 5EB2A2E32107DED300EB4B69 /* ChannelTests */, - 5EB2A2F42109284500EB4B69 /* InteropTestsMultipleChannels */, - 5E7D71B1210B9EC8001EA6BA /* InteropTestsCallOptions */, - 5E0282E5215AA697007AC99D /* UnitTests */, - 5E3B95A121CAC6C500C0A151 /* APIv2Tests */, - B0BB3EF6225E795F008DA580 /* MacTests */, + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 5E0282E4215AA697007AC99D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-CronetTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 5E3B95A021CAC6C500C0A151 /* Resources */ = { - isa = PBXResourcesBuildPhase; + D11CB94CF56A1E53760D29D8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E7D71B0210B9EC8001EA6BA /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + inputFileListPaths = ( ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EAD6D221E27047400002378 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-resources.sh\"\n"; + showEnvVarsInLog = 0; }; - 5EB2A2E22107DED300EB4B69 /* Resources */ = { - isa = PBXResourcesBuildPhase; + E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MacTests-checkManifestLockResult.txt", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 5EB2A2F32109284500EB4B69 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E7D71AD210954A8001EA6BA /* TestCertificates.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E41F208177CC000EF4AD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E42F2081856B000EF4AD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E440208185CE000EF4AD /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EC5E44E20818948000EF4AD /* TestCertificates.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EE84BEF1D4717E40050C6CC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63423F421B150A5F006CF63C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63E240D01B6C63DC005F3B0E /* TestCertificates.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84111BE15179000708E8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84211BE15267000708E8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84321BE15294000708E8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6379CC531BE17709001BC0A1 /* TestCertificates.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84411BE152B5000708E8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B0BB3EF5225E795F008DA580 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B0BB3F0A225EA511008DA580 /* TestCertificates.bundle in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 021B3B1F545989843EBC9A4B /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ChannelTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 0617B5294978A95BEBBFF733 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalCleartextCFStream-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 2865C6386D677998F861E183 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsCallOptions-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh", - "${PODS_ROOT}/CronetFramework/Cronet.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-macOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemoteCFStream-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemote-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 4EB2FFF40BB00AD0C545D7EF /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; + F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); @@ -1531,1849 +785,78 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSL-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-UnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 693DD0B453431D64EA24FD66 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalCleartext-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 80E2DDD2EC04A4009F45E933 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CronetUnitTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 8AD3130D3C58A0FB32FF2A36 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsMultipleChannels-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 8D685CB612835DB3F7A6F14A /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", - "${PODS_ROOT}/CronetFramework/Cronet.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-AllTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 95FBC48B743503845678584F /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9AD0B5E94F2AA5962EA6AA36 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh", - "${PODS_ROOT}/CronetFramework/Cronet.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RxLibraryUnitTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsRemoteWithCronet-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C17B826BBD02FDD4A5F355AF /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-MacTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh", - "${PODS_ROOT}/CronetFramework/Cronet.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-APIv2Tests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-UnitTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-InteropTestsLocalSSLCFStream-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-CoreCronetEnd2EndTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 5E0282E2215AA697007AC99D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E3B959E21CAC6C500C0A151 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E3B95A521CAC6C500C0A151 /* APIv2Tests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E7D71AE210B9EC8001EA6BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E7D71B5210B9EC9001EA6BA /* InteropTestsCallOptions.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EAD6D201E27047400002378 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EB2A2E02107DED300EB4B69 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EB2A2E72107DED300EB4B69 /* ChannelTests.m in Sources */, - 5EB5C3AA21656CEA00ADC300 /* ChannelPoolTest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EB2A2F12109284500EB4B69 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EB2A2F82109284500EB4B69 /* InteropTestsMultipleChannels.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E41D208177CC000EF4AD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EC5E42B2081782C000EF4AD /* InteropTestsRemote.m in Sources */, - 5EC5E42C20817832000EF4AD /* InteropTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E42D2081856B000EF4AD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EC5E43B208185A7000EF4AD /* InteropTestsLocalCleartext.m in Sources */, - 5EC5E43D208185B0000EF4AD /* GRPCClientTests.m in Sources */, - 5EC5E43C208185AD000EF4AD /* InteropTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EC5E43E208185CE000EF4AD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EC5E44D208185F0000EF4AD /* InteropTestsLocalSSL.m in Sources */, - 5EC5E44C208185EC000EF4AD /* InteropTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5EE84BED1D4717E40050C6CC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5EE84BFE1D471D400050C6CC /* InteropTests.m in Sources */, - 5EE84BF41D4717E40050C6CC /* InteropTestsRemoteWithCronet.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63423F401B150A5F006CF63C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63715F561B780C020029CB0B /* InteropTestsLocalCleartext.m in Sources */, - 6379CC511BE1683B001BC0A1 /* InteropTestsRemote.m in Sources */, - 63E240CE1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m in Sources */, - 6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */, - 635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */, - 63DC842E1BE15278000708E8 /* RxLibraryUnitTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 635697C31B14FC11007A7283 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 635697CD1B14FC11007A7283 /* Tests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC840F1BE15179000708E8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC841E1BE15180000708E8 /* RxLibraryUnitTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC841F1BE15267000708E8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC842F1BE1527D000708E8 /* InteropTests.m in Sources */, - 6379CC501BE16703001BC0A1 /* InteropTestsRemote.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC84301BE15294000708E8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC844F1BE15353000708E8 /* InteropTestsLocalSSL.m in Sources */, - 6379CC4D1BE1662A001BC0A1 /* InteropTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 63DC843F1BE152B5000708E8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 63DC84501BE153AA000708E8 /* GRPCClientTests.m in Sources */, - 63DC844E1BE15350000708E8 /* InteropTestsLocalCleartext.m in Sources */, - 6379CC4E1BE1662B001BC0A1 /* InteropTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B0BB3EF3225E795F008DA580 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B0BB3F07225E7AB5008DA580 /* APIv2Tests.m in Sources */, - B0BB3F08225E7ABA008DA580 /* UnitTests.m in Sources */, - B071230B22669EED004B64A1 /* StressTests.m in Sources */, - B0BB3F05225E7A9F008DA580 /* InteropTestsRemote.m in Sources */, - B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */, - B0BB3F03225E7A44008DA580 /* InteropTestsLocalCleartext.m in Sources */, - B0BB3F04225E7A8D008DA580 /* RxLibraryUnitTests.m in Sources */, - B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */, - B0BB3F0B225EB110008DA580 /* InteropTests.m in Sources */, - B0BB3F02225E7A3C008DA580 /* InteropTestsLocalSSL.m in Sources */, - B0BB3F06225E7AAD008DA580 /* GRPCClientTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 5E0282ED215AA697007AC99D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */; - }; - 5E7D71B9210B9EC9001EA6BA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5E7D71B8210B9EC9001EA6BA /* PBXContainerItemProxy */; - }; - 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */; - }; - 5EAD6D2B1E27047400002378 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5EAD6D2A1E27047400002378 /* PBXContainerItemProxy */; - }; - 5EB2A2EB2107DED300EB4B69 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5EB2A2EA2107DED300EB4B69 /* PBXContainerItemProxy */; - }; - 5EB2A2FC2109284500EB4B69 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5EB2A2FB2109284500EB4B69 /* PBXContainerItemProxy */; - }; - 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */; - }; - 63423F4C1B150A5F006CF63C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */; - }; - 63DC841A1BE15179000708E8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 63DC84191BE15179000708E8 /* PBXContainerItemProxy */; - }; - 63DC842A1BE15267000708E8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 63DC84291BE15267000708E8 /* PBXContainerItemProxy */; - }; - 63DC843B1BE15294000708E8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 63DC843A1BE15294000708E8 /* PBXContainerItemProxy */; - }; - 63DC844A1BE152B5000708E8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 635697C61B14FC11007A7283 /* Tests */; - targetProxy = 63DC84491BE152B5000708E8 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 5E0282EE215AA697007AC99D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = UnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; - }; - name = Debug; - }; - 5E0282EF215AA697007AC99D /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = UnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; - }; - name = Test; - }; - 5E0282F0215AA697007AC99D /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = UnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; - }; - name = Cronet; - }; - 5E0282F1215AA697007AC99D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = UnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; - }; - name = Release; - }; - 5E1228981E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", - "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", - "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", - "GRPC_TEST_OBJC=1", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Test; - }; - 5E1228991E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Test; - }; - 5E12289A1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DB1F4391AF69D20D38D74B67 /* Pods-AllTests.test.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E12289B1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 781089FAE980F51F88A3BE0B /* Pods-RxLibraryUnitTests.test.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E12289C1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E12289D1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D13BEC8181B8E678A1B52F54 /* Pods-InteropTestsLocalSSL.test.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E12289E1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E12289F1E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 6793C9D019CB268C5BB491A2 /* Pods-CoreCronetEnd2EndTests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; - }; - name = Test; - }; - 5E1228A01E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Test; - }; - 5E1228A11E4D400F00E8504F /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B226619DC4E709E0FFFF94B8 /* Pods-CronetUnitTests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; - INFOPLIST_FILE = CronetUnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "\"${PODS_ROOT}/../../../..\" $(inherited)"; - }; - name = Test; - }; - 5E3B95A821CAC6C500C0A151 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1286B30AD74CB64CD91FB17D /* Pods-APIv2Tests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E3B95A921CAC6C500C0A151 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 51F2A64B7AADBA1B225B132E /* Pods-APIv2Tests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5E3B95AA21CAC6C500C0A151 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 8C233E85C3EB45B3CAE52EDF /* Pods-APIv2Tests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5E3B95AB21CAC6C500C0A151 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 12B238CD1702393C2BA5DE80 /* Pods-APIv2Tests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = APIv2Tests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.APIv2Tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5E7D71BB210B9EC9001EA6BA /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3A98DF08852F60AF1D96481D /* Pods-InteropTestsCallOptions.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5E7D71BC210B9EC9001EA6BA /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = A25967A0D40ED14B3287AD81 /* Pods-InteropTestsCallOptions.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5E7D71BD210B9EC9001EA6BA /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 73D2DF07027835BA0FB0B1C0 /* Pods-InteropTestsCallOptions.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5E7D71BE210B9EC9001EA6BA /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C9172F9020E8C97A470D7250 /* Pods-InteropTestsCallOptions.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsCallOptions/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsCallOptions; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_CONFIGURATION_BUILD_DIR}/BoringSSL\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/Protobuf\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/RemoteTest\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/gRPC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Core-072e2d32\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/gRPC-ProtoRPC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/gRPC-RxLibrary\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/gRPC-Core\"", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; - }; - name = Debug; - }; - 5E8A5DAD1D3840B4000F8BC4 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; - }; - name = Release; - }; - 5EAD6D2C1E27047400002378 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 64F68A9A6A63CC930DD30A6E /* Pods-CronetUnitTests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "PB_FIELD_32BIT=1", - "PB_NO_PACKED_STRUCTS=1", - "GRPC_SHADOW_BORINGSSL_SYMBOLS=1", - ); - INFOPLIST_FILE = CronetUnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "\"${PODS_ROOT}/../../../..\" $(inherited)"; - }; - name = Debug; - }; - 5EAD6D2D1E27047400002378 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 386712AEACF7C2190C4B8B3F /* Pods-CronetUnitTests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; - INFOPLIST_FILE = CronetUnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "\"${PODS_ROOT}/../../../..\" $(inherited)"; - }; - name = Cronet; - }; - 5EAD6D2E1E27047400002378 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 02192CF1FF9534E3D18C65FC /* Pods-CronetUnitTests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; - INFOPLIST_FILE = CronetUnitTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "\"${PODS_ROOT}/../../../..\" $(inherited)"; - }; - name = Release; - }; - 5EB2A2EC2107DED300EB4B69 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F9E48EF5ACB1F38825171C5F /* Pods-ChannelTests.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = ChannelTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5EB2A2ED2107DED300EB4B69 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = BED74BC8ABF9917C66175879 /* Pods-ChannelTests.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = ChannelTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5EB2A2EE2107DED300EB4B69 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 90E63AD3C4A1E3E6BC745096 /* Pods-ChannelTests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = ChannelTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5EB2A2EF2107DED300EB4B69 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D52B92A7108602F170DA8091 /* Pods-ChannelTests.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = ChannelTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.ChannelTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5EB2A2FD2109284500EB4B69 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3CADF86203B9D03EA96C359D /* Pods-InteropTestsMultipleChannels.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5EB2A2FE2109284500EB4B69 /* Test */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = EA8B122ACDE73E3AAA0E4A19 /* Pods-InteropTestsMultipleChannels.test.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Test; - }; - 5EB2A2FF2109284500EB4B69 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1295CCBD1082B4A7CFCED95F /* Pods-InteropTestsMultipleChannels.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5EB2A3002109284500EB4B69 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 2650FEF00956E7924772F9D9 /* Pods-InteropTestsMultipleChannels.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = InteropTestsMultipleChannels/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsMultipleChannels; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", - "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", - "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Cronet; - }; - 5EC3C7A11D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Cronet; - }; - 5EC3C7A21D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */; - buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; - }; - 5EC3C7A31D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; - }; - 5EC3C7A41D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - ); - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; - }; - 5EC3C7A51D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5E0282E2215AA697007AC99D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E0282E9215AA697007AC99D /* NSErrorUnitTests.m in Sources */, + 5E7F4880227782C1006656AD /* APIv2Tests.m in Sources */, + 5E7F487D22778256006656AD /* ChannelPoolTest.m in Sources */, + 5E7F488722778AEA006656AD /* GRPCClientTests.m in Sources */, + 5E7F487E22778256006656AD /* ChannelTests.m in Sources */, + 5E7F488B22778B5D006656AD /* RxLibraryUnitTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; }; - 5EC3C7A61D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; + 5E7F485522775B15006656AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, + 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */, + 5E7F488522778A88006656AD /* InteropTests.m in Sources */, + 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */, + 5E7F486522775B41006656AD /* CronetUnitTests.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; }; - 5EC3C7A71D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; - }; - name = Cronet; + 5EA476F02272816A000F72FC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, + 5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */, + 5E7F487922778226006656AD /* InteropTestsMultipleChannels.m in Sources */, + 5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */, + 5EA4770322736178000F72FC /* InteropTestsLocalSSL.m in Sources */, + 5E7F488422778A88006656AD /* InteropTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; }; - 5EC3C7A81D4FC18C000330E2 /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_COMPILE_WITH_CRONET=1", - "GRPC_CRONET_WITH_PACKET_COALESCING=1", - "GRPC_TEST_OBJC=1", - ); - INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Cronet; + B0BB3EF3225E795F008DA580 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0BB3F08225E7ABA008DA580 /* NSErrorUnitTests.m in Sources */, + 5E7F488D22778C85006656AD /* InteropTestsLocalSSL.m in Sources */, + 5E7F488E22778C87006656AD /* InteropTestsLocalCleartext.m in Sources */, + 5E7F489022778C95006656AD /* RxLibraryUnitTests.m in Sources */, + B071230B22669EED004B64A1 /* StressTests.m in Sources */, + B0D39B9A2266F3CB00A4078D /* StressTestsSSL.m in Sources */, + 5E7F488322778A88006656AD /* InteropTests.m in Sources */, + 5E3F14862278BFFF007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, + 5E7F488C22778C60006656AD /* APIv2Tests.m in Sources */, + 5E7F488F22778C8C006656AD /* InteropTestsRemote.m in Sources */, + B0D39B9C2266FF9800A4078D /* StressTestsCleartext.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; }; - 5EC5E426208177CC000EF4AD /* Debug */ = { +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5E0282EE215AA697007AC99D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */; + baseConfigurationReference = A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3396,15 +879,16 @@ INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; }; name = Debug; }; - 5EC5E427208177CC000EF4AD /* Test */ = { + 5E0282EF215AA697007AC99D /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C17F57E5BCB989AB1C2F1F25 /* Pods-InteropTestsRemoteCFStream.test.xcconfig */; + baseConfigurationReference = 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3422,28 +906,19 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "$(inherited)", - "PB_FIELD_32BIT=1", - "PB_NO_PACKED_STRUCTS=1", - "GRPC_CFSTREAM=1", - ); INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; }; name = Test; }; - 5EC5E428208177CC000EF4AD /* Cronet */ = { + 5E0282F0215AA697007AC99D /* Cronet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4A1A42B2E941CCD453489E5B /* Pods-InteropTestsRemoteCFStream.cronet.xcconfig */; + baseConfigurationReference = E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3464,15 +939,16 @@ INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; }; name = Cronet; }; - 5EC5E429208177CC000EF4AD /* Release */ = { + 5E0282F1215AA697007AC99D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */; + baseConfigurationReference = EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -3493,24 +969,75 @@ INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteCFStream; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; }; name = Release; }; - 5EC5E4372081856C000EF4AD /* Debug */ = { + 5E1228981E4D400F00E8504F /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", + "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", + "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", + "GRPC_TEST_OBJC=1", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Test; + }; + 5E7F485F22775B15006656AD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */; + baseConfigurationReference = EC66920112123D2DB1CB7F6C /* Pods-CronetTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3520,28 +1047,39 @@ CODE_SIGN_STYLE = Automatic; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Pods/CronetFramework", + ); GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../..; }; name = Debug; }; - 5EC5E4382081856C000EF4AD /* Test */ = { + 5E7F486022775B15006656AD /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */; + baseConfigurationReference = 5AB9A82F289D548D6B8816F9 /* Pods-CronetTests.test.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3549,38 +1087,38 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "PB_FIELD_32BIT=1", - "PB_NO_PACKED_STRUCTS=1", - "GRPC_CFSTREAM=1", + "$(PROJECT_DIR)/Pods/CronetFramework", ); + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../..; }; name = Test; }; - 5EC5E4392081856C000EF4AD /* Cronet */ = { + 5E7F486122775B15006656AD /* Cronet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */; + baseConfigurationReference = 20F6A3D59D0EE091E2D43953 /* Pods-CronetTests.cronet.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3588,28 +1126,38 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Pods/CronetFramework", + ); GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../..; }; name = Cronet; }; - 5EC5E43A2081856C000EF4AD /* Release */ = { + 5E7F486222775B15006656AD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */; + baseConfigurationReference = 7F4F42EBAF311E9F84FCA32E /* Pods-CronetTests.release.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3617,28 +1165,38 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Pods/CronetFramework", + ); GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartextCFStream; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = ../../..; }; name = Release; }; - 5EC5E448208185CE000EF4AD /* Debug */ = { + 5EA476FC2272816B000F72FC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3EB55EF291706E3DDE23C3B7 /* Pods-InteropTestsLocalSSLCFStream.debug.xcconfig */; + baseConfigurationReference = 680439AC2BC8761EDD54A1EA /* Pods-InteropTests.debug.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3650,26 +1208,31 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 5EC5E449208185CE000EF4AD /* Test */ = { + 5EA476FD2272816B000F72FC /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */; + baseConfigurationReference = 070266E2626EB997B54880A3 /* Pods-InteropTests.test.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3678,66 +1241,31 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "$(inherited)", - "PB_FIELD_32BIT=1", - "PB_NO_PACKED_STRUCTS=1", - "GRPC_CFSTREAM=1", - ); INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Test; }; - 5EC5E44A208185CE000EF4AD /* Cronet */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Cronet; - }; - 5EC5E44B208185CE000EF4AD /* Release */ = { + 5EA476FE2272816B000F72FC /* Cronet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */; + baseConfigurationReference = CDF6CC70B8BF9D10EFE7D199 /* Pods-InteropTests.cronet.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; @@ -3746,88 +1274,96 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSLCFStream; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5EE84BF91D4717E40050C6CC /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - ); - INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 5EE84BFA1D4717E40050C6CC /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "COCOAPODS=1", - "$(inherited)", - "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", - "GRPC_COMPILE_WITH_CRONET=1", - ); - INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; }; - name = Release; + name = Cronet; }; - 63423F4E1B150A5F006CF63C /* Debug */ = { + 5EA476FF2272816B000F72FC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */; + baseConfigurationReference = F6A7EECACBB4849DDD3F450A /* Pods-InteropTests.release.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; }; - name = Debug; + name = Release; }; - 63423F4F1B150A5F006CF63C /* Release */ = { + 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", "$(inherited)", + "HOST_PORT_REMOTE=$(HOST_PORT_REMOTE)", + "HOST_PORT_LOCALSSL=$(HOST_PORT_LOCALSSL)", + "HOST_PORT_LOCAL=$(HOST_PORT_LOCAL)", + "GRPC_TEST_OBJC=1", + "GRPC_COMPILE_WITH_CRONET=1", ); - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_NAME = "$(TARGET_NAME)"; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; }; - name = Release; + name = Cronet; }; 635697D91B14FC11007A7283 /* Debug */ = { isa = XCBuildConfiguration; @@ -3909,128 +1445,6 @@ }; name = Release; }; - 635697DC1B14FC11007A7283 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 635697DD1B14FC11007A7283 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 63DC841C1BE15179000708E8 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 63DC841D1BE15179000708E8 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */; - buildSettings = { - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 63DC842C1BE15267000708E8 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 63DC842D1BE15267000708E8 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */; - buildSettings = { - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 63DC843D1BE15294000708E8 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 63DC843E1BE15294000708E8 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */; - buildSettings = { - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 63DC844C1BE152B5000708E8 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 63DC844D1BE152B5000708E8 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */; - buildSettings = { - INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; B0BB3EFD225E795F008DA580 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = E3ACD4D5902745976D9C2229 /* Pods-MacTests.debug.xcconfig */; @@ -4193,123 +1607,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5E3B95A721CAC6C500C0A151 /* Build configuration list for PBXNativeTarget "APIv2Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E3B95A821CAC6C500C0A151 /* Debug */, - 5E3B95A921CAC6C500C0A151 /* Test */, - 5E3B95AA21CAC6C500C0A151 /* Cronet */, - 5E3B95AB21CAC6C500C0A151 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E7D71BA210B9EC9001EA6BA /* Build configuration list for PBXNativeTarget "InteropTestsCallOptions" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E7D71BB210B9EC9001EA6BA /* Debug */, - 5E7D71BC210B9EC9001EA6BA /* Test */, - 5E7D71BD210B9EC9001EA6BA /* Cronet */, - 5E7D71BE210B9EC9001EA6BA /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5E8A5DAC1D3840B4000F8BC4 /* Debug */, - 5E12289F1E4D400F00E8504F /* Test */, - 5EC3C7A71D4FC18C000330E2 /* Cronet */, - 5E8A5DAD1D3840B4000F8BC4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EAD6D2F1E27047400002378 /* Build configuration list for PBXNativeTarget "CronetUnitTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EAD6D2C1E27047400002378 /* Debug */, - 5E1228A11E4D400F00E8504F /* Test */, - 5EAD6D2D1E27047400002378 /* Cronet */, - 5EAD6D2E1E27047400002378 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EB2A2F02107DED300EB4B69 /* Build configuration list for PBXNativeTarget "ChannelTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EB2A2EC2107DED300EB4B69 /* Debug */, - 5EB2A2ED2107DED300EB4B69 /* Test */, - 5EB2A2EE2107DED300EB4B69 /* Cronet */, - 5EB2A2EF2107DED300EB4B69 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EB2A3012109284500EB4B69 /* Build configuration list for PBXNativeTarget "InteropTestsMultipleChannels" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EB2A2FD2109284500EB4B69 /* Debug */, - 5EB2A2FE2109284500EB4B69 /* Test */, - 5EB2A2FF2109284500EB4B69 /* Cronet */, - 5EB2A3002109284500EB4B69 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EC5E42A208177CD000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsRemoteCFStream" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EC5E426208177CC000EF4AD /* Debug */, - 5EC5E427208177CC000EF4AD /* Test */, - 5EC5E428208177CC000EF4AD /* Cronet */, - 5EC5E429208177CC000EF4AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EC5E4362081856C000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartextCFStream" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EC5E4372081856C000EF4AD /* Debug */, - 5EC5E4382081856C000EF4AD /* Test */, - 5EC5E4392081856C000EF4AD /* Cronet */, - 5EC5E43A2081856C000EF4AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EC5E447208185CE000EF4AD /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSLCFStream" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5EC5E448208185CE000EF4AD /* Debug */, - 5EC5E449208185CE000EF4AD /* Test */, - 5EC5E44A208185CE000EF4AD /* Cronet */, - 5EC5E44B208185CE000EF4AD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */ = { + 5E7F485E22775B15006656AD /* Build configuration list for PBXNativeTarget "CronetTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 5EE84BF91D4717E40050C6CC /* Debug */, - 5E1228A01E4D400F00E8504F /* Test */, - 5EC3C7A81D4FC18C000330E2 /* Cronet */, - 5EE84BFA1D4717E40050C6CC /* Release */, + 5E7F485F22775B15006656AD /* Debug */, + 5E7F486022775B15006656AD /* Test */, + 5E7F486122775B15006656AD /* Cronet */, + 5E7F486222775B15006656AD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */ = { + 5EA477002272816B000F72FC /* Build configuration list for PBXNativeTarget "InteropTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 63423F4E1B150A5F006CF63C /* Debug */, - 5E12289A1E4D400F00E8504F /* Test */, - 5EC3C7A21D4FC18C000330E2 /* Cronet */, - 63423F4F1B150A5F006CF63C /* Release */, + 5EA476FC2272816B000F72FC /* Debug */, + 5EA476FD2272816B000F72FC /* Test */, + 5EA476FE2272816B000F72FC /* Cronet */, + 5EA476FF2272816B000F72FC /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -4325,61 +1640,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 635697DC1B14FC11007A7283 /* Debug */, - 5E1228991E4D400F00E8504F /* Test */, - 5EC3C7A11D4FC18C000330E2 /* Cronet */, - 635697DD1B14FC11007A7283 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 63DC841B1BE15179000708E8 /* Build configuration list for PBXNativeTarget "RxLibraryUnitTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 63DC841C1BE15179000708E8 /* Debug */, - 5E12289B1E4D400F00E8504F /* Test */, - 5EC3C7A31D4FC18C000330E2 /* Cronet */, - 63DC841D1BE15179000708E8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 63DC842B1BE15267000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsRemote" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 63DC842C1BE15267000708E8 /* Debug */, - 5E12289C1E4D400F00E8504F /* Test */, - 5EC3C7A41D4FC18C000330E2 /* Cronet */, - 63DC842D1BE15267000708E8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 63DC843C1BE15294000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalSSL" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 63DC843D1BE15294000708E8 /* Debug */, - 5E12289D1E4D400F00E8504F /* Test */, - 5EC3C7A51D4FC18C000330E2 /* Cronet */, - 63DC843E1BE15294000708E8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 63DC844B1BE152B5000708E8 /* Build configuration list for PBXNativeTarget "InteropTestsLocalCleartext" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 63DC844C1BE152B5000708E8 /* Debug */, - 5E12289E1E4D400F00E8504F /* Test */, - 5EC3C7A61D4FC18C000330E2 /* Cronet */, - 63DC844D1BE152B5000708E8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; B0BB3EFC225E795F008DA580 /* Build configuration list for PBXNativeTarget "MacTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme deleted file mode 100644 index a2560fee029..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme deleted file mode 100644 index acae965bed0..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/ChannelTests.xcscheme +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme deleted file mode 100644 index e62edd397a5..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Asan.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Asan.xcscheme deleted file mode 100644 index 0a597e756ec..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Asan.xcscheme +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Tsan.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Tsan.xcscheme deleted file mode 100644 index 5fe60b96920..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests_Tsan.xcscheme +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme similarity index 77% rename from src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme rename to src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme index e0d1d1fdcac..aea349a06cc 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/APIv2Tests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme @@ -1,6 +1,6 @@ @@ -32,9 +32,9 @@ skipped = "NO"> @@ -43,7 +43,7 @@ @@ -73,9 +73,9 @@ diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetUnitTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetUnitTests.xcscheme deleted file mode 100644 index ea711e09e97..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetUnitTests.xcscheme +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme similarity index 75% rename from src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme rename to src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme index 412bf6a0143..a2b1614b991 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemote.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme @@ -1,6 +1,6 @@ + buildForAnalyzing = "NO"> @@ -32,9 +32,9 @@ skipped = "NO"> @@ -44,20 +44,11 @@ - - - - @@ -84,9 +75,18 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> + + + + + buildConfiguration = "Debug"> - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme deleted file mode 100644 index 11b41c92140..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartext.xcscheme +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme deleted file mode 100644 index fe766de928e..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalCleartextCFStream.xcscheme +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme deleted file mode 100644 index 37135b3ad36..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSL.xcscheme +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme deleted file mode 100644 index bd663276493..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsLocalSSLCFStream.xcscheme +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme deleted file mode 100644 index 1b4c1f5e51c..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsMultipleChannels.xcscheme +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme deleted file mode 100644 index 33a5ded038b..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteCFStream.xcscheme +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme deleted file mode 100644 index 1d211115f75..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme index f84ac7fc741..fbd2d08f219 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/MacTests.xcscheme @@ -51,7 +51,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme deleted file mode 100644 index 77f567db3d4..00000000000 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme index 3af3555f48e..d20a9e5ae7b 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme @@ -23,10 +23,9 @@ -#import "version.h" +#import "../version.h" #define TEST_TIMEOUT 16 diff --git a/src/objective-c/tests/UnitTests/Info.plist b/src/objective-c/tests/UnitTests/Info.plist deleted file mode 100644 index 6c40a6cd0c4..00000000000 --- a/src/objective-c/tests/UnitTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/NSErrorUnitTests.m similarity index 96% rename from src/objective-c/tests/UnitTests/UnitTests.m rename to src/objective-c/tests/UnitTests/NSErrorUnitTests.m index 4dcb8c08d28..8a4f03a4460 100644 --- a/src/objective-c/tests/UnitTests/UnitTests.m +++ b/src/objective-c/tests/UnitTests/NSErrorUnitTests.m @@ -22,11 +22,11 @@ #import "../../GRPCClient/private/NSError+GRPC.h" -@interface UnitTests : XCTestCase +@interface NSErrorUnitTests : XCTestCase @end -@implementation UnitTests +@implementation NSErrorUnitTests - (void)testNSError { const char *kDetails = "test details"; diff --git a/src/objective-c/tests/RxLibraryUnitTests.m b/src/objective-c/tests/UnitTests/RxLibraryUnitTests.m similarity index 100% rename from src/objective-c/tests/RxLibraryUnitTests.m rename to src/objective-c/tests/UnitTests/RxLibraryUnitTests.m diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 8c768cb85be..24185c561ec 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -43,98 +43,12 @@ XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ echo "TIME: $(date)" -# Retry the test for up to 3 times when return code is 65, due to Xcode issue: -# http://www.openradar.me/29785686 -# The issue seems to be a connectivity issue to Xcode simulator so only retry -# the first xcodebuild command -retries=0 -while [ $retries -lt 3 ]; do - return_code=0 - out=$(xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme AllTests \ - -destination name="iPhone 8" \ - HOST_PORT_LOCALSSL=localhost:5051 \ - HOST_PORT_LOCAL=localhost:5050 \ - HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ - test 2>&1 \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - ) || return_code=$? - if [ $return_code == 65 ] && [[ $out == *"DTXProxyChannel error 1"* ]]; then - echo "$out" - echo "Failed with code 65 (DTXProxyChannel error 1); retry." - retries=$(($retries+1)) - elif [ $return_code == 0 ]; then - echo "$out" - break - else - echo "$out" - echo "Failed with code $return_code." - exit 1 - fi -done -if [ $retries == 3 ]; then - echo "Failed with code 65 for 3 times; abort." - exit 1 -fi - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme CoreCronetEnd2EndTests \ - -destination name="iPhone 8" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme CoreCronetEnd2EndTests_Asan \ - -destination name="iPhone 6" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme CoreCronetEnd2EndTests_Tsan \ - -destination name="iPhone 6" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme CronetUnitTests \ - -destination name="iPhone 8" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme InteropTestsRemoteWithCronet \ - -destination name="iPhone 8" \ - HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme InteropTestsRemoteCFStream \ + -scheme InteropTests \ -destination name="iPhone 8" \ + HOST_PORT_LOCALSSL=localhost:5051 \ + HOST_PORT_LOCAL=localhost:5050 \ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ | egrep -v "$XCODEBUILD_FILTER" \ @@ -144,9 +58,11 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme InteropTestsLocalCleartextCFStream \ + -scheme UnitTests \ -destination name="iPhone 8" \ + HOST_PORT_LOCALSSL=localhost:5051 \ HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ | egrep -v "$XCODEBUILD_FILTER" \ | egrep -v '^$' \ @@ -155,39 +71,9 @@ xcodebuild \ echo "TIME: $(date)" xcodebuild \ -workspace Tests.xcworkspace \ - -scheme InteropTestsLocalSSLCFStream \ + -scheme CronetTests \ -destination name="iPhone 8" \ HOST_PORT_LOCALSSL=localhost:5051 \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme UnitTests \ - -destination name="iPhone 8" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme ChannelTests \ - -destination name="iPhone 8" \ - test \ - | egrep -v "$XCODEBUILD_FILTER" \ - | egrep -v '^$' \ - | egrep -v "(GPBDictionary|GPBArray)" - - -echo "TIME: $(date)" -xcodebuild \ - -workspace Tests.xcworkspace \ - -scheme APIv2Tests \ - -destination name="iPhone 8" \ HOST_PORT_LOCAL=localhost:5050 \ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ From 7e8dec516ba4fe886dcdbc57fa3a4ab772004cf7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 30 Apr 2019 13:52:37 -0700 Subject: [PATCH 017/676] Unify deployment target --- .../tests/Tests.xcodeproj/project.pbxproj | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 1295731641b..1f05899bd60 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -877,7 +877,6 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -907,7 +906,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -937,7 +935,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -967,7 +964,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1054,7 +1050,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -1094,7 +1089,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; @@ -1133,7 +1127,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; @@ -1172,7 +1165,6 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_INHIBIT_ALL_WARNINGS = YES; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CronetTests; @@ -1208,7 +1200,6 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -1242,7 +1233,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; @@ -1275,7 +1265,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; @@ -1308,7 +1297,6 @@ CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; From 2e8e7e4838ecf179cbb2ee8e943c27cec6dc7668 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 30 Apr 2019 16:56:43 -0700 Subject: [PATCH 018/676] Initialize Cronet only once --- src/objective-c/tests/InteropTests/InteropTests.m | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 164d571d125..260afb83e6f 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -110,10 +110,13 @@ BOOL isRemoteInteropTest(NSString *host) { + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET - // Cronet setup - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; + static dispatch_once_t *enableCronet; + dispatch_once(enableCronet, ^{ + // Cronet setup + [Cronet setHttp2Enabled:YES]; + [Cronet start]; + [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; + }); #endif #ifdef GRPC_CFSTREAM setenv(kCFStreamVarName, "1", 1); From d6c98bf82e46daed0841382d59d112a36979fb17 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 30 Apr 2019 18:25:06 -0700 Subject: [PATCH 019/676] Fix Cronet multiple initialization problem --- .../CronetTests/CoreCronetEnd2EndTests.mm | 10 ++--- .../tests/CronetTests/CronetUnitTests.mm | 13 ++----- .../InteropTestsRemoteWithCronet.m | 4 ++ src/objective-c/tests/EnableCronet.h | 34 +++++++++++++++++ src/objective-c/tests/EnableCronet.m | 38 +++++++++++++++++++ .../tests/InteropTests/InteropTests.h | 5 +++ .../tests/InteropTests/InteropTests.m | 14 ++++--- .../tests/Tests.xcodeproj/project.pbxproj | 8 ++++ .../xcschemes/CronetTests.xcscheme | 5 +++ 9 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 src/objective-c/tests/EnableCronet.h create mode 100644 src/objective-c/tests/EnableCronet.m diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index 2fac1be3d0e..3a753d4a4a4 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -49,6 +49,8 @@ #import #include +#import "../EnableCronet.h" + typedef struct fullstack_secure_fixture_data { char *localaddr; } fullstack_secure_fixture_data; @@ -176,13 +178,7 @@ static char *roots_filename; grpc_init(); - [Cronet setHttp2Enabled:YES]; - [Cronet enableTestCertVerifierForTesting]; - NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory - inDomains:NSUserDomainMask] lastObject]; - NSLog(@"Documents directory: %@", url); - [Cronet start]; - [Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:YES]; + enableCronet(); } // The tearDown() function is run after all test cases finish running diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 2a861032caf..b17bc334479 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -20,6 +20,8 @@ #import #import +#import "../EnableCronet.h" + #import #import #import @@ -61,16 +63,7 @@ static void drain_cq(grpc_completion_queue *cq) { grpc_test_init(1, argv); grpc_init(); - - [Cronet setHttp2Enabled:YES]; - [Cronet setSslKeyLogFileName:@"Documents/key"]; - [Cronet enableTestCertVerifierForTesting]; - NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory - inDomains:NSUserDomainMask] lastObject]; - NSLog(@"Documents directory: %@", url); - [Cronet start]; - [Cronet startNetLogToFile:@"Documents/cronet_netlog.json" logBytes:YES]; - + enableCronet(); init_ssl(); } diff --git a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m index 25041ae5eb1..a2a79c46316 100644 --- a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m +++ b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m @@ -44,6 +44,10 @@ static int32_t kRemoteInteropServerOverhead = 12; return kRemoteSSLHost; } ++ (BOOL)useCronet { + return YES; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } diff --git a/src/objective-c/tests/EnableCronet.h b/src/objective-c/tests/EnableCronet.h new file mode 100644 index 00000000000..e544e76345d --- /dev/null +++ b/src/objective-c/tests/EnableCronet.h @@ -0,0 +1,34 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifdef GRPC_COMPILE_WITH_CRONET + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enable Cronet for once. + */ +void enableCronet(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/objective-c/tests/EnableCronet.m b/src/objective-c/tests/EnableCronet.m new file mode 100644 index 00000000000..ff6e4612d88 --- /dev/null +++ b/src/objective-c/tests/EnableCronet.m @@ -0,0 +1,38 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifdef GRPC_COMPILE_WITH_CRONET + +#import +#import "EnableCronet.h" + +void enableCronet(void) { + static dispatch_once_t enableCronet; + dispatch_once(&enableCronet, ^{ + [Cronet setHttp2Enabled:YES]; + [Cronet setSslKeyLogFileName:@"Documents/key"]; + [Cronet enableTestCertVerifierForTesting]; + NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask] lastObject]; + NSLog(@"Documents directory: %@", url); + [Cronet start]; + [Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:YES]; + }); +} + +#endif diff --git a/src/objective-c/tests/InteropTests/InteropTests.h b/src/objective-c/tests/InteropTests/InteropTests.h index 038f24b62e5..cffa90ac497 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.h +++ b/src/objective-c/tests/InteropTests/InteropTests.h @@ -59,4 +59,9 @@ */ + (NSString *)hostNameOverride; +/** + * Whether to use Cronet for all the v1 API tests in the test suite. + */ ++ (BOOL)useCronet; + @end diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 260afb83e6f..3204f689c48 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -37,6 +37,7 @@ #import #import "InteropTestsBlockCallbacks.h" +#import "../enableCronet.h" #define TEST_TIMEOUT 32 @@ -107,16 +108,17 @@ BOOL isRemoteInteropTest(NSString *host) { return nil; } ++ (BOOL)useCronet { + return NO; +} + + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET - static dispatch_once_t *enableCronet; - dispatch_once(enableCronet, ^{ - // Cronet setup - [Cronet setHttp2Enabled:YES]; - [Cronet start]; + enableCronet(); + if ([self useCronet]) { [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; - }); + } #endif #ifdef GRPC_CFSTREAM setenv(kCFStreamVarName, "1", 1); diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 1f05899bd60..c226e29d83b 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; 5E3F14862278BFFF007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; + 5E3F148D22792856007C6D90 /* EnableCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* EnableCronet.m */; }; + 5E3F148E22792AF5007C6D90 /* EnableCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* EnableCronet.m */; }; 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; }; 5E7F486522775B41006656AD /* CronetUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.mm */; }; 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */; }; @@ -92,6 +94,8 @@ 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSErrorUnitTests.m; sourceTree = ""; }; 5E3F14822278B42D007C6D90 /* InteropTestsBlockCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InteropTestsBlockCallbacks.h; sourceTree = ""; }; 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsBlockCallbacks.m; sourceTree = ""; }; + 5E3F1487227918AA007C6D90 /* EnableCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EnableCronet.m; sourceTree = ""; }; + 5E3F148A227918C4007C6D90 /* EnableCronet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EnableCronet.h; sourceTree = ""; }; 5E7F485922775B15006656AD /* CronetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7F486622776AD8006656AD /* Cronet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cronet.framework; path = Pods/CronetFramework/Cronet.framework; sourceTree = ""; }; 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; @@ -392,6 +396,8 @@ 635697C91B14FC11007A7283 /* Tests */ = { isa = PBXGroup; children = ( + 5E3F148A227918C4007C6D90 /* EnableCronet.h */, + 5E3F1487227918AA007C6D90 /* EnableCronet.m */, 5EAFE8271F8EFB87007F2189 /* version.h */, 635697D71B14FC11007A7283 /* Supporting Files */, ); @@ -813,6 +819,7 @@ buildActionMask = 2147483647; files = ( 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, + 5E3F148D22792856007C6D90 /* EnableCronet.m in Sources */, 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */, 5E7F488522778A88006656AD /* InteropTests.m in Sources */, 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */, @@ -825,6 +832,7 @@ buildActionMask = 2147483647; files = ( 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, + 5E3F148E22792AF5007C6D90 /* EnableCronet.m in Sources */, 5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */, 5E7F487922778226006656AD /* InteropTestsMultipleChannels.m in Sources */, 5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */, diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme index aea349a06cc..ac8cfc971c8 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme @@ -37,6 +37,11 @@ BlueprintName = "CronetTests" ReferencedContainer = "container:Tests.xcodeproj"> + + + + From 8f0934d739c340824ff070c76c75000928fa83e5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 May 2019 11:39:01 -0700 Subject: [PATCH 020/676] Another Cronet mulitple initialization problem --- .../tests/InteropTests/InteropTestsMultipleChannels.m | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m index c0beb107fad..506d7807de2 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m @@ -27,6 +27,7 @@ #import #import "InteropTestsBlockCallbacks.h" +#import "../EnableCronet" #define NSStringize_helper(x) #x #define NSStringize(x) @NSStringize_helper(x) @@ -88,10 +89,7 @@ dispatch_once_t initCronet; _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:nil]; - dispatch_once(&initCronet, ^{ - [Cronet setHttp2Enabled:YES]; - [Cronet start]; - }); + enableCronet(); // Default stack with remote host GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; From a0cf95a88abc573882329ac9ea4e7d7544725b15 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 May 2019 11:40:11 -0700 Subject: [PATCH 021/676] Add log to debug --- src/objective-c/tests/EnableCronet.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/tests/EnableCronet.m b/src/objective-c/tests/EnableCronet.m index ff6e4612d88..b618ec74706 100644 --- a/src/objective-c/tests/EnableCronet.m +++ b/src/objective-c/tests/EnableCronet.m @@ -24,6 +24,7 @@ void enableCronet(void) { static dispatch_once_t enableCronet; dispatch_once(&enableCronet, ^{ + NSLog(@"enableCronet()"); [Cronet setHttp2Enabled:YES]; [Cronet setSslKeyLogFileName:@"Documents/key"]; [Cronet enableTestCertVerifierForTesting]; From f9defc92794d2ee3bcd7db729bea77c0d06c206e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 May 2019 13:12:32 -0700 Subject: [PATCH 022/676] prototype issue --- src/objective-c/tests/EnableCronet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/EnableCronet.h b/src/objective-c/tests/EnableCronet.h index e544e76345d..720aace4075 100644 --- a/src/objective-c/tests/EnableCronet.h +++ b/src/objective-c/tests/EnableCronet.h @@ -25,7 +25,7 @@ extern "C" { /** * Enable Cronet for once. */ -void enableCronet(); +void enableCronet(void); #ifdef __cplusplus } From bcbff503ec3f3afd87978822a29b19dc9b4fddf6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 May 2019 14:20:26 -0700 Subject: [PATCH 023/676] nit --- src/objective-c/tests/InteropTests/InteropTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 3204f689c48..91fdd0fd841 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -37,7 +37,7 @@ #import #import "InteropTestsBlockCallbacks.h" -#import "../enableCronet.h" +#import "../EnableCronet.h" #define TEST_TIMEOUT 32 From 4ca3431715e660a08d94e1776837269867768cf1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 1 May 2019 15:48:11 -0700 Subject: [PATCH 024/676] nit fix --- .../tests/InteropTests/InteropTestsMultipleChannels.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m index 506d7807de2..58946825f98 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m @@ -27,7 +27,7 @@ #import #import "InteropTestsBlockCallbacks.h" -#import "../EnableCronet" +#import "../EnableCronet.h" #define NSStringize_helper(x) #x #define NSStringize(x) @NSStringize_helper(x) From cf20870fcf2455bd2c075df842cb5afb606532b5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 May 2019 09:43:44 -0700 Subject: [PATCH 025/676] Add license info to new files --- .../GRPCClient/private/GRPCCall+V2API.h | 18 ++++++++++++++++++ .../GRPCClient/private/GRPCCallInternal.h | 17 +++++++++++++++++ .../GRPCClient/private/GRPCCallInternal.m | 18 ++++++++++++++++++ .../InterceptorSample/AppDelegate.m | 18 ++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/src/objective-c/GRPCClient/private/GRPCCall+V2API.h b/src/objective-c/GRPCClient/private/GRPCCall+V2API.h index 34871ad5c2a..22bf16962c6 100644 --- a/src/objective-c/GRPCClient/private/GRPCCall+V2API.h +++ b/src/objective-c/GRPCClient/private/GRPCCall+V2API.h @@ -1,3 +1,21 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + @interface GRPCCall (V2API) - (instancetype)initWithHost:(NSString *)host diff --git a/src/objective-c/GRPCClient/private/GRPCCallInternal.h b/src/objective-c/GRPCClient/private/GRPCCallInternal.h index 28bc1e46aff..ac2d1cba2ec 100644 --- a/src/objective-c/GRPCClient/private/GRPCCallInternal.h +++ b/src/objective-c/GRPCClient/private/GRPCCallInternal.h @@ -1,3 +1,20 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ #import diff --git a/src/objective-c/GRPCClient/private/GRPCCallInternal.m b/src/objective-c/GRPCClient/private/GRPCCallInternal.m index e4edcedf36c..32e38158fad 100644 --- a/src/objective-c/GRPCClient/private/GRPCCallInternal.m +++ b/src/objective-c/GRPCClient/private/GRPCCallInternal.m @@ -1,3 +1,21 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #import "GRPCCallInternal.h" #import diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m index 1b9f2c85dac..659f7528d22 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/AppDelegate.m @@ -1,3 +1,21 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #import "AppDelegate.h" @implementation AppDelegate From ca541c9c5f5389f9123c16f77fbcca7fcad40ae1 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Thu, 9 May 2019 11:37:19 -0700 Subject: [PATCH 026/676] Address review comments. --- test/cpp/qps/client_callback.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index ade23e13a72..d22264d21e3 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -293,9 +293,6 @@ class CallbackStreamingPingPongReactor final gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after // next_issue_time - if (ctx_->alarm_ == nullptr) { - ctx_->alarm_.reset(new Alarm); - } ctx_->alarm_->experimental().Set(next_issue_time, [this](bool ok) { write_time_ = UsageTimer::Now(); StartWrite(client_->request()); From b11a36e4b3ecb511cb78826a8379a793083a8a76 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 May 2019 14:12:39 -0700 Subject: [PATCH 027/676] mark marshaller WIP --- src/objective-c/GRPCClient/GRPCCall.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 1a941571951..cf66531ab0c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -182,7 +182,7 @@ extern NSString *const kGRPCTrailersKey; /** * Issued when a decompressed message is received from the server. The message is decompressed, and - * deserialized if a marshaller is provided to the call. + * deserialized if a marshaller is provided to the call (marshaller is work in progress). */ - (void)didReceiveData:(id)data; @@ -271,7 +271,8 @@ extern NSString *const kGRPCTrailersKey; - (void)cancel; /** - * Send a message to the server. The data is subject to marshaller serialization and compression. + * Send a message to the server. The data is subject to marshaller serialization and compression + * (marshaller is work in progress). */ - (void)writeData:(id)data; From a01674e3dcd190f2c3b9b7e9d6ac31396b1abd1c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 9 May 2019 14:15:17 -0700 Subject: [PATCH 028/676] Fix interop tests types --- src/objective-c/tests/InteropTests.m | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 93316c0ff5a..690c5cee0a2 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -175,13 +175,13 @@ BOOL isRemoteInteropTest(NSString *host) { initWithDispatchQueue:(dispatch_queue_t)dispatchQueue startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; @@ -198,13 +198,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; @@ -214,11 +214,11 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @implementation HookInterceptorFactory { void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); - void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_writeDataHook)(id data, GRPCInterceptorManager *manager); void (^_finishHook)(GRPCInterceptorManager *manager); void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); - void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_responseDataHook)(id data, GRPCInterceptorManager *manager); void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); @@ -229,13 +229,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager initWithDispatchQueue:(dispatch_queue_t)dispatchQueue startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { @@ -272,11 +272,11 @@ receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, @implementation HookIntercetpor { void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); - void (^_writeDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_writeDataHook)(id data, GRPCInterceptorManager *manager); void (^_finishHook)(GRPCInterceptorManager *manager); void (^_receiveNextMessagesHook)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); void (^_responseHeaderHook)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager); - void (^_responseDataHook)(NSData *data, GRPCInterceptorManager *manager); + void (^_responseDataHook)(id data, GRPCInterceptorManager *manager); void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); @@ -298,13 +298,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))writeDataHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager))receiveNextMessagesHook responseHeaderHook:(void (^)(NSDictionary *initialMetadata, GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(NSData *data, GRPCInterceptorManager *manager))responseDataHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager))responseCloseHook didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { @@ -332,7 +332,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } -- (void)writeData:(NSData *)data { +- (void)writeData:(id )data { if (_writeDataHook) { _writeDataHook(data, _manager); } @@ -356,7 +356,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } -- (void)didReceiveData:(NSData *)data { +- (void)didReceiveData:(id )data { if (_responseDataHook) { _responseDataHook(data, _manager); } @@ -1355,22 +1355,18 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { startCount++; - NSLog(@"Interceptor - started call, %@, %@", requestOptions, callOptions); XCTAssertEqualObjects(requestOptions.host, [[self class] host]); XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; } - writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataHook:^(id data, GRPCInterceptorManager *manager) { writeDataCount++; - NSLog(@"Interceptor - send data, %@", data); - XCTAssertNotEqual(data.length, 0); [manager writeNextInterceptorWithData:data]; } finishHook:^(GRPCInterceptorManager *manager) { finishCount++; - NSLog(@"Interceptor - finish call"); [manager finishNextInterceptor]; } receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { @@ -1383,10 +1379,9 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager NSLog(@"Interceptor - received initial metadata, %@", initialMetadata); [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; } - responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataHook:^(id data, GRPCInterceptorManager *manager) { responseDataCount++; NSLog(@"Interceptor - received data, %@", data); - XCTAssertNotEqual(data.length, 0); [manager forwardPreviousIntercetporWithData:data]; } responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, @@ -1491,7 +1486,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; } - writeDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + writeDataHook:^(id data, GRPCInterceptorManager *manager) { writeDataCount++; if (index < kCancelAfterWrites) { [manager writeNextInterceptorWithData:data]; @@ -1517,7 +1512,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager responseHeaderCount++; [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; } - responseDataHook:^(NSData *data, GRPCInterceptorManager *manager) { + responseDataHook:^(id data, GRPCInterceptorManager *manager) { responseDataCount++; [manager forwardPreviousIntercetporWithData:data]; } From aa79909f94cd1f1dbfab8c15407b83415d5f3804 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 10 May 2019 10:44:41 -0700 Subject: [PATCH 029/676] Bump version to v1.21.0-pre1 --- BUILD | 2 +- build.yaml | 2 +- doc/g_stands_for.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD b/BUILD index 5c05c9e4549..b066f384ca0 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.0-dev" +version = "1.21.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index fabb041b386..3b40102a675 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.0-dev + version: 1.21.0-pre1 filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index b926db191de..ba0ba58fbfc 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -20,4 +20,4 @@ - 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) - 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) - 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) -- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/master) +- 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x) From 1aefcbb357538ec22c102a6c1e939114742068ca Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 10 May 2019 10:48:05 -0700 Subject: [PATCH 030/676] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 33 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index accc28807b4..f0c14873d76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.0-dev") +set(PACKAGE_VERSION "1.21.0-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index c4a62228b64..b68529b5b0f 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.0-dev -CSHARP_VERSION = 1.21.0-dev +CPP_VERSION = 1.21.0-pre1 +CSHARP_VERSION = 1.21.0-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1dc2258538a..6f445a71929 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.0-dev' - version = '0.0.8-dev' + # version = '1.21.0-pre1' + version = '0.0.8-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.0-dev' + grpc_version = '1.21.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index cbf0a4b2924..3df5539e9fe 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.0-dev' + version = '1.21.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 0e905bd97bd..af515fb529b 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.0-dev' + version = '1.21.0-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index df86ef7ed34..df8fcae0b41 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.0-dev' + version = '1.21.0-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index b3c7a55a2e1..5458725ad76 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.0-dev' + version = '1.21.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 04d9f35cf03..e0587098a66 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.21.0dev - 1.21.0dev + 1.21.0RC1 + 1.21.0RC1 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 166c2d39b35..8aeb99f2566 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.0-dev"; } +grpc::string Version() { return "1.21.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 1b2602e219d..402d251446a 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.0-dev"; + public const string CurrentVersion = "1.21.0-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index b018aac0f8e..67647c7a96c 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.0-dev + 1.21.0-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 8c7718f727f..b8e247f8613 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.0-dev +set VERSION=1.21.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 88b8d2975d6..d7db86900c7 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.0-dev' + v = '1.21.0-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index fcbdfb21539..b011dd53275 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.21.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 87516de11e8..28b45771ace 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.21.0-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 43b3fa629ff..7d6f86c9bfe 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.0dev" +#define PHP_GRPC_VERSION "1.21.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 651f8f778f2..3a9cfc7a5e9 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.0.dev0""" +__version__ = """1.21.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index e430cc20a6d..d8434992dd5 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index d716b953f4b..cbe46b76837 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 2bb47aaf133..cfa296588e8 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e1c4f3df694..54261c77f1d 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index b484a7ba478..9a5e728adfb 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 21981ee79d2..7cd0ffa30c1 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 8ce4fdb627d..1a5e9f5385e 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index cca795b64ec..30c4b3adae0 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.0.dev' + VERSION = '1.21.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 5604e215b58..19c79e4f854 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.0.dev' + VERSION = '1.21.0.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 22d04c5a1af..a91af1be0d2 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.0.dev0' +VERSION = '1.21.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index d5874920752..0a399e0d1d7 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0-dev +PROJECT_NUMBER = 1.21.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ab0968b3252..e314e7e969e 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0-dev +PROJECT_NUMBER = 1.21.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 4e711fab644fb30c2e0cae6cb7f01aa56e9dbd75 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 May 2019 13:51:14 -0700 Subject: [PATCH 031/676] Add method to validate and set service config json --- .../grpcpp/support/channel_arguments_impl.h | 23 ++++++++++++++++++- src/cpp/common/channel_arguments.cc | 15 +++++++++++- .../end2end/service_config_end2end_test.cc | 8 ++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 0efeadca880..631992d28c3 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -40,8 +40,24 @@ class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, /// concrete setters are provided. -class ChannelArguments { +class ChannelArguments : private ::grpc::GrpcLibraryCodegen { public: + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(ChannelArguments* args) : args_(args) {} + + /// Validates \a service_config_json. If valid, set the service config and + /// returns an empty string. If invalid, returns the validation error. + grpc::string ValidateAndSetServiceConfigJSON( + const grpc::string& service_config_json); + + private: + ChannelArguments* args_; + }; + ChannelArguments(); ~ChannelArguments(); @@ -125,6 +141,11 @@ class ChannelArguments { return out; } + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + private: friend class grpc_impl::SecureChannelCredentials; friend class grpc::testing::ChannelArgumentsTest; diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 932139890fe..faea3316c58 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -23,6 +23,7 @@ #include #include #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" @@ -35,7 +36,7 @@ ChannelArguments::ChannelArguments() { } ChannelArguments::ChannelArguments(const ChannelArguments& other) - : strings_(other.strings_) { + : ::grpc::GrpcLibraryCodegen(), strings_(other.strings_) { args_.reserve(other.args_.size()); auto list_it_dst = strings_.begin(); auto list_it_src = other.strings_.begin(); @@ -215,4 +216,16 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } +grpc::string +ChannelArguments::experimental_type::ValidateAndSetServiceConfigJSON( + const grpc::string& service_config_json) { + grpc_error* error = GRPC_ERROR_NONE; + grpc_core::ServiceConfig::Create(service_config_json.c_str(), &error); + if (error != GRPC_ERROR_NONE) { + return grpc_error_string(error); + } + args_->SetServiceConfigJSON(service_config_json); + return ""; +} + } // namespace grpc_impl diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index b3299232763..74a304f6b26 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -231,7 +231,9 @@ class ServiceConfigEnd2endTest : public ::testing::Test { std::shared_ptr BuildChannelWithDefaultServiceConfig() { ChannelArguments args; - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); + EXPECT_THAT(args.experimental().ValidateAndSetServiceConfigJSON( + ValidDefaultServiceConfig()), + ::testing::StrEq("")); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); return ::grpc::CreateCustomChannel("fake:///", creds_, args); @@ -239,6 +241,10 @@ class ServiceConfigEnd2endTest : public ::testing::Test { std::shared_ptr BuildChannelWithInvalidDefaultServiceConfig() { ChannelArguments args; + EXPECT_THAT( + args.experimental().ValidateAndSetServiceConfigJSON( + InvalidDefaultServiceConfig()), + ::testing::HasSubstr("failed to parse JSON for service config")); args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); From d115e39a4a301321b647782c14ddb771b7129e01 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 May 2019 15:04:23 -0700 Subject: [PATCH 032/676] Add initialization note --- include/grpcpp/support/channel_arguments_impl.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 631992d28c3..e31f7e80db0 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -40,6 +40,9 @@ class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, /// concrete setters are provided. +/// This class derives from GrpcLibraryCodegen so that gRPC is initialized +/// before ValidateAndSetServiceConfigJSON is used. (Service config validation +/// methods are registered at initialization.) class ChannelArguments : private ::grpc::GrpcLibraryCodegen { public: /// NOTE: class experimental_type is not part of the public API of this class. From 3a9c96301a259d469ff5cc975c008f402af2cbe8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 May 2019 15:05:43 -0700 Subject: [PATCH 033/676] s/set/sets --- include/grpcpp/support/channel_arguments_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index e31f7e80db0..9a034078033 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -52,7 +52,7 @@ class ChannelArguments : private ::grpc::GrpcLibraryCodegen { public: explicit experimental_type(ChannelArguments* args) : args_(args) {} - /// Validates \a service_config_json. If valid, set the service config and + /// Validates \a service_config_json. If valid, sets the service config and /// returns an empty string. If invalid, returns the validation error. grpc::string ValidateAndSetServiceConfigJSON( const grpc::string& service_config_json); From 15d8fd9b23d1b01bb8da7563dcddb22c09288bb8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 May 2019 16:09:48 -0700 Subject: [PATCH 034/676] Missing error unref --- src/cpp/common/channel_arguments.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index faea3316c58..84b786299c6 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -222,7 +222,9 @@ ChannelArguments::experimental_type::ValidateAndSetServiceConfigJSON( grpc_error* error = GRPC_ERROR_NONE; grpc_core::ServiceConfig::Create(service_config_json.c_str(), &error); if (error != GRPC_ERROR_NONE) { - return grpc_error_string(error); + grpc::string return_value = grpc_error_string(error); + GRPC_ERROR_UNREF(error); + return return_value; } args_->SetServiceConfigJSON(service_config_json); return ""; From f299391f15927561927282a495c50e8d97c1ea16 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 14 May 2019 10:36:49 -0700 Subject: [PATCH 035/676] Add GrpcLibraryInitializer --- src/cpp/common/channel_arguments.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 84b786299c6..48dfe815042 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" @@ -30,7 +31,12 @@ namespace grpc_impl { +namespace { +::grpc::internal::GrpcLibraryInitializer g_gli_initializer; +} // namespace + ChannelArguments::ChannelArguments() { + g_gli_initializer.summon(); // This will be ignored if used on the server side. SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + grpc::Version()); } From e68316dda5c607118c9a20e79d46a2b99c72fccb Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 14 May 2019 12:07:05 -0700 Subject: [PATCH 036/676] Fix errors from clang format script --- src/core/lib/surface/completion_queue.cc | 18 ++++++++---------- test/core/surface/completion_queue_test.cc | 3 ++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 18cc15d8b7a..2b60033c42c 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -862,11 +862,10 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)), - GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, functor, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::LONG)), + GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); } @@ -1352,11 +1351,10 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, callback, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, callback, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::LONG)), + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 214d673cdf6..35a67387335 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -463,7 +463,8 @@ static void test_callback(void) { gpr_mu_lock(&shutdown_mu); while (!got_shutdown) { // Wait for the shutdown callback to complete. - gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + gpr_cv_wait(&shutdown_cv, &shutdown_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); } gpr_mu_unlock(&shutdown_mu); } From a73f22bd73d72223136658d8ce1cd3da46d6457f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 14 May 2019 12:10:17 -0700 Subject: [PATCH 037/676] Make the executor SHORT instead of LONG. --- src/core/lib/surface/completion_queue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 2b60033c42c..8dce0e01141 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -864,7 +864,7 @@ static void cq_end_op_for_callback( auto* functor = static_cast(tag); GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, functor, grpc_core::Executor::Scheduler( - grpc_core::ExecutorJobType::LONG)), + grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); @@ -1353,7 +1353,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, callback, grpc_core::Executor::Scheduler( - grpc_core::ExecutorJobType::LONG)), + grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_NONE); } From 091c12ad79049558c80bc3831c0198ea216c6673 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 14 May 2019 12:55:20 -0700 Subject: [PATCH 038/676] Fix clang errors --- src/core/lib/surface/completion_queue.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 8dce0e01141..cdf1020051f 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -862,10 +862,11 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, functor, - grpc_core::Executor::Scheduler( - grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); } @@ -1351,10 +1352,11 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(functor_callback, callback, - grpc_core::Executor::Scheduler( - grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, callback, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 172bb1b30f15b1d656603190c5bad2f426ac1354 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 14 May 2019 15:04:39 -0700 Subject: [PATCH 039/676] Whitelist internal code path to use ApplicationExecCtx --- src/core/lib/surface/completion_queue.cc | 27 +++++++++++++++--------- src/core/lib/surface/completion_queue.h | 2 +- src/core/lib/surface/server.cc | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index cdf1020051f..d040e91b796 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -201,7 +201,7 @@ struct cq_vtable { bool (*begin_op)(grpc_completion_queue* cq, void* tag); void (*end_op)(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal); grpc_event (*next)(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, @@ -359,19 +359,19 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal = false); static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal = false); static void cq_end_op_for_callback(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal = false); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -679,7 +679,8 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { + void* done_arg, grpc_cq_completion* storage, + bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -759,7 +760,8 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { + void* done_arg, grpc_cq_completion* storage, + bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -831,7 +833,8 @@ static void functor_callback(void* arg, grpc_error* error) { static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage) { + grpc_cq_completion* storage, + bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -862,19 +865,23 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); - GRPC_CLOSURE_SCHED( + if (internal) { + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); + } else { + GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, functor, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_REF(error)); + } GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { - cq->vtable->end_op(cq, tag, error, done, done_arg, storage); + void* done_arg, grpc_cq_completion* storage, bool internal) { + cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); } typedef struct { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index d60fe6d6efe..f5b0822fcb4 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,7 +77,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 2377c4d8f23..19f61c548d6 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx, } grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event, - rc, &rc->completion); + rc, &rc->completion, true); } static void publish_new_rpc(void* arg, grpc_error* error) { From c7343ea03d4e9382dec1ff9c25f5629c68fc87bb Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Tue, 14 May 2019 16:20:21 -0700 Subject: [PATCH 040/676] Unsubscribe all connectivity callbacks on Channel.close --- src/python/grpcio/grpc/_channel.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 1272ee802bc..f566fd698ad 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -1000,6 +1000,11 @@ def _unsubscribe(state, callback): break +def _unsubscribe_all(state): + with state.lock: + del state.callbacks_and_connectivities[:] + + def _augment_options(base_options, compression): compression_option = _compression.create_channel_option(compression) return tuple(base_options) + compression_option + (( @@ -1067,6 +1072,7 @@ class Channel(grpc.Channel): _common.encode(method), request_serializer, response_deserializer) def _close(self): + _unsubscribe_all(self._connectivity_state) self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') cygrpc.fork_unregister_channel(self) _moot(self._connectivity_state) From d2876cc6b6a67e02163d258e33faf9ff53f0bcef Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 May 2019 10:40:01 -0700 Subject: [PATCH 041/676] Fix Windows vs libuv platform detection in cares code --- .../resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc | 2 +- src/core/lib/iomgr/port.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index ce39007f905..85f5cd84ca0 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -18,7 +18,7 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && defined(GPR_WINDOWS) +#if GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) #include diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index d387de5b13c..0b3681868f7 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -44,6 +44,7 @@ #elif defined(GPR_WINDOWS) #define GRPC_WINSOCK_SOCKET 1 #define GRPC_WINDOWS_SOCKETUTILS 1 +#define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER #elif defined(GPR_ANDROID) #define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1 From 710cbb02e6bdbd2efea0b63ec8ac34ebea27a0ca Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 May 2019 11:15:12 -0700 Subject: [PATCH 042/676] libuv cares: scope manual localhost resolution to only Windows --- BUILD | 4 +- BUILD.gn | 4 +- CMakeLists.txt | 4 + Makefile | 4 + build.yaml | 4 +- config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- grpc.gyp | 4 + package.xml | 4 +- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 19 ----- .../grpc_ares_wrapper_libuv_nonwindows.cc | 39 +++++++++ .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 64 +++----------- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 4 +- .../c_ares/grpc_ares_wrapper_windows_inner.cc | 83 +++++++++++++++++++ ...ws.h => grpc_ares_wrapper_windows_inner.h} | 0 src/python/grpcio/grpc_core_dependencies.py | 2 + tools/doxygen/Doxyfile.core.internal | 4 +- .../generated/sources_and_headers.json | 10 ++- 21 files changed, 184 insertions(+), 85 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc rename src/core/ext/filters/client_channel/resolver/dns/c_ares/{grpc_ares_wrapper_libuv_windows.h => grpc_ares_wrapper_windows_inner.h} (100%) diff --git a/BUILD b/BUILD index b066f384ca0..dafe1031e17 100644 --- a/BUILD +++ b/BUILD @@ -1600,13 +1600,15 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", ], hdrs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h", ], external_deps = [ "cares", diff --git a/BUILD.gn b/BUILD.gn index 47b2747065d..be43b5e4217 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -318,14 +318,16 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index f0c14873d76..eed7ac07e0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1299,9 +1299,11 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -2696,9 +2698,11 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc diff --git a/Makefile b/Makefile index b68529b5b0f..29828e60fe2 100644 --- a/Makefile +++ b/Makefile @@ -3771,9 +3771,11 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ @@ -5116,9 +5118,11 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ diff --git a/build.yaml b/build.yaml index 3b40102a675..91f9b671d29 100644 --- a/build.yaml +++ b/build.yaml @@ -779,8 +779,8 @@ filegroups: - name: grpc_resolver_dns_ares headers: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h src: - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -790,9 +790,11 @@ filegroups: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc plugin: grpc_resolver_dns_ares uses: - grpc_base diff --git a/config.m4 b/config.m4 index d90a8e94e6d..2f512cc8400 100644 --- a/config.m4 +++ b/config.m4 @@ -409,9 +409,11 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ diff --git a/config.w32 b/config.w32 index 70ac245d9fa..d4943e8893e 100644 --- a/config.w32 +++ b/config.w32 @@ -384,9 +384,11 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_nonwindows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows_inner.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6f445a71929..c969446a957 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -561,8 +561,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 3df5539e9fe..850d7b5c387 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -537,8 +537,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', @@ -867,9 +867,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', @@ -1190,8 +1192,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 6e229a5ab71..d13b007c395 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -471,8 +471,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) @@ -804,9 +804,11 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 833a0b48715..5b7bf481dd2 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -591,9 +591,11 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', @@ -1352,9 +1354,11 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', diff --git a/package.xml b/package.xml index e0587098a66..7f9a7888f90 100644 --- a/package.xml +++ b/package.xml @@ -476,8 +476,8 @@ + - @@ -809,9 +809,11 @@ + + diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index fdbb8969a1f..252fba916ff 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -23,13 +23,6 @@ #include -#include "src/core/ext/filters/client_channel/parse_address.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/gpr/string.h" - bool grpc_ares_query_ipv6() { /* The libuv grpc code currently does not have the code to probe for this, * so we assume for now that IPv6 is always available in contexts where this @@ -37,16 +30,4 @@ bool grpc_ares_query_ipv6() { return true; } -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; -} - #endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc new file mode 100644 index 00000000000..dc8d051e2af --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc @@ -0,0 +1,39 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) && !defined(GPR_WINDOWS) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { + return false; +} + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 1232fc9d57c..d4f3944fdc7 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,65 +19,27 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) +#if GRPC_ARES == 1 && defined(GRPC_UV) && defined(GPR_WINDOWS) #include #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -bool inner_maybe_resolve_localhost_manually_locked( +bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during manual localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during manual localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; + grpc_core::UniquePtr* addrs) { + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; } -#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 60398c6aedd..fcb47eb5b58 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -19,13 +19,13 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && defined(GPR_WINDOWS) +#if GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) #include #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc new file mode 100644 index 00000000000..ee37144eca7 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc @@ -0,0 +1,83 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during manual localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during manual localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h similarity index 100% rename from src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h rename to src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 61524eb7fc9..db78061a63d 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -383,9 +383,11 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 293a6e1f9c1..4905bd365d0 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -945,14 +945,16 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index de8015ac52a..b358e855c07 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9178,8 +9178,8 @@ ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" ], "is_filegroup": true, "language": "c", @@ -9191,14 +9191,16 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc" ], "third_party": false, "type": "filegroup" From a0b32609ffcba5d4ac8bb042a7ae492aa493d926 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 May 2019 14:46:15 -0700 Subject: [PATCH 043/676] Moved code back into one file with a #ifdef --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 4 -- Makefile | 4 -- build.yaml | 2 - config.m4 | 2 - config.w32 | 2 - gRPC-Core.podspec | 2 - grpc.gemspec | 2 - grpc.gyp | 4 -- package.xml | 2 - .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 23 ++++++++++ .../grpc_ares_wrapper_libuv_nonwindows.cc | 39 ---------------- .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 45 ------------------- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 2 +- .../c_ares/grpc_ares_wrapper_windows_inner.cc | 4 +- src/core/lib/iomgr/port.h | 3 +- src/python/grpcio/grpc_core_dependencies.py | 2 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 2 - 20 files changed, 28 insertions(+), 122 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc diff --git a/BUILD b/BUILD index dafe1031e17..03507cc1777 100644 --- a/BUILD +++ b/BUILD @@ -1599,8 +1599,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", diff --git a/BUILD.gn b/BUILD.gn index be43b5e4217..465e808b719 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -323,8 +323,6 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index eed7ac07e0c..eb011f445c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1299,8 +1299,6 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc @@ -2698,8 +2696,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc diff --git a/Makefile b/Makefile index 29828e60fe2..98c3ce29f66 100644 --- a/Makefile +++ b/Makefile @@ -3771,8 +3771,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ @@ -5118,8 +5116,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ diff --git a/build.yaml b/build.yaml index 91f9b671d29..8f3f6ad929f 100644 --- a/build.yaml +++ b/build.yaml @@ -790,8 +790,6 @@ filegroups: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc diff --git a/config.m4 b/config.m4 index 2f512cc8400..f29cb0c705b 100644 --- a/config.m4 +++ b/config.m4 @@ -409,8 +409,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ diff --git a/config.w32 b/config.w32 index d4943e8893e..4f0225974f7 100644 --- a/config.w32 +++ b/config.w32 @@ -384,8 +384,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + - "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_nonwindows.cc " + - "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows_inner.cc " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 850d7b5c387..57f1db47edb 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -867,8 +867,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', diff --git a/grpc.gemspec b/grpc.gemspec index d13b007c395..aedcf57573b 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -804,8 +804,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc ) diff --git a/grpc.gyp b/grpc.gyp index 5b7bf481dd2..5feaabd456d 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -591,8 +591,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', @@ -1354,8 +1352,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', diff --git a/package.xml b/package.xml index 7f9a7888f90..273274acaaf 100644 --- a/package.xml +++ b/package.xml @@ -809,8 +809,6 @@ - - diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index 252fba916ff..eb0b3dab4a4 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -23,6 +23,13 @@ #include +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + bool grpc_ares_query_ipv6() { /* The libuv grpc code currently does not have the code to probe for this, * so we assume for now that IPv6 is always available in contexts where this @@ -30,4 +37,20 @@ bool grpc_ares_query_ipv6() { return true; } +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { +#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +#else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ + return false; +#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ +} + #endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc deleted file mode 100644 index dc8d051e2af..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && defined(GRPC_UV) && !defined(GPR_WINDOWS) - -#include - -#include "src/core/ext/filters/client_channel/parse_address.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/gpr/string.h" - -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { - return false; -} - -#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc deleted file mode 100644 index d4f3944fdc7..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && defined(GRPC_UV) && defined(GPR_WINDOWS) - -#include - -#include "src/core/ext/filters/client_channel/parse_address.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/gpr/string.h" - -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; -} - -#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index fcb47eb5b58..e48f9501752 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -45,4 +45,4 @@ bool grpc_ares_maybe_resolve_localhost_manually_locked( return out; } -#endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */ +#endif /* GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc index ee37144eca7..1331a6a67f5 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc @@ -19,7 +19,7 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) +#if GRPC_ARES == 1 && defined(GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY) #include @@ -80,4 +80,4 @@ bool inner_maybe_resolve_localhost_manually_locked( return false; } -#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ +#endif /* GRPC_ARES == 1 && defined(GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY) */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 0b3681868f7..605692ac0d6 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -44,7 +44,8 @@ #elif defined(GPR_WINDOWS) #define GRPC_WINSOCK_SOCKET 1 #define GRPC_WINDOWS_SOCKETUTILS 1 -#define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER +#define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER 1 +#define GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY 1 #elif defined(GPR_ANDROID) #define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1 diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index db78061a63d..c9217aded63 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -383,8 +383,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 4905bd365d0..765abbebd42 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -950,8 +950,6 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b358e855c07..512c2d51d48 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9196,8 +9196,6 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_nonwindows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc" From e2571a708f28c780c15bd5669b0021cb1c004b2a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 May 2019 15:43:04 -0700 Subject: [PATCH 044/676] Fix sanity --- .../resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h index ed40e58f7cc..783b781154c 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H #include @@ -30,5 +30,5 @@ bool inner_maybe_resolve_localhost_manually_locked( grpc_core::UniquePtr* addrs, char** host, char** port); -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H \ +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H \ */ From 718d0ac621596861d677bf5428b2484409dec37a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 May 2019 15:53:45 -0700 Subject: [PATCH 045/676] Fix typo --- BUILD.gn | 2 +- build.yaml | 2 +- gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 4 ++-- grpc.gemspec | 2 +- package.xml | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- tools/run_tests/generated/sources_and_headers.json | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 465e808b719..7357d0f9595 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -318,7 +318,6 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", @@ -326,6 +325,7 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", diff --git a/build.yaml b/build.yaml index 8f3f6ad929f..f6ce3d79ae8 100644 --- a/build.yaml +++ b/build.yaml @@ -779,8 +779,8 @@ filegroups: - name: grpc_resolver_dns_ares headers: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h src: - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index c969446a957..22cb70b80a3 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -561,8 +561,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 57f1db47edb..7338b01099f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -537,8 +537,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', @@ -1190,8 +1190,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index aedcf57573b..b0ea43b9d92 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -471,8 +471,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) diff --git a/package.xml b/package.xml index 273274acaaf..560b422d94d 100644 --- a/package.xml +++ b/package.xml @@ -476,8 +476,8 @@ - + diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 765abbebd42..483e639be66 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -945,7 +945,6 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ @@ -953,6 +952,7 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv. src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 512c2d51d48..de08e38a838 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9178,8 +9178,8 @@ ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" ], "is_filegroup": true, "language": "c", @@ -9191,14 +9191,14 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrappe_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" ], "third_party": false, "type": "filegroup" From 4242c85bed501bac246eeca814429b163a37d125 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 14 May 2019 15:26:56 -0700 Subject: [PATCH 046/676] Consolidate conditional localhost resolution into existing file --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 2 - Makefile | 2 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 2 - package.xml | 2 - .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 68 +++++++++++++++ .../resolver/dns/c_ares/grpc_ares_wrapper.h | 8 -- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 17 ---- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 6 -- .../dns/c_ares/grpc_ares_wrapper_windows.cc | 13 --- .../c_ares/grpc_ares_wrapper_windows_inner.cc | 83 ------------------- .../c_ares/grpc_ares_wrapper_windows_inner.h | 34 -------- src/python/grpcio/grpc_core_dependencies.py | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 7 +- 22 files changed, 70 insertions(+), 191 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc delete mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h diff --git a/BUILD b/BUILD index 03507cc1777..2cffca4ffc2 100644 --- a/BUILD +++ b/BUILD @@ -1601,12 +1601,10 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", ], hdrs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h", ], external_deps = [ "cares", diff --git a/BUILD.gn b/BUILD.gn index 7357d0f9595..d3c1186f7a6 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -324,8 +324,6 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index eb011f445c1..7457016c3cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1301,7 +1301,6 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -2698,7 +2697,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc diff --git a/Makefile b/Makefile index 98c3ce29f66..99238d17428 100644 --- a/Makefile +++ b/Makefile @@ -3773,7 +3773,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ @@ -5118,7 +5117,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ diff --git a/build.yaml b/build.yaml index f6ce3d79ae8..25f80af37e2 100644 --- a/build.yaml +++ b/build.yaml @@ -780,7 +780,6 @@ filegroups: headers: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h src: - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -792,7 +791,6 @@ filegroups: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc - - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc plugin: grpc_resolver_dns_ares uses: - grpc_base diff --git a/config.m4 b/config.m4 index f29cb0c705b..bb30be56910 100644 --- a/config.m4 +++ b/config.m4 @@ -411,7 +411,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ diff --git a/config.w32 b/config.w32 index 4f0225974f7..c9faa8d9ac8 100644 --- a/config.w32 +++ b/config.w32 @@ -386,7 +386,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + - "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows_inner.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 22cb70b80a3..3f42684be03 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -562,7 +562,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 7338b01099f..6d369950b09 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -538,7 +538,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', @@ -869,7 +868,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', @@ -1191,7 +1189,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index b0ea43b9d92..5a34687b4d9 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -472,7 +472,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) @@ -806,7 +805,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) - s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 5feaabd456d..1cc6e46b4be 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -593,7 +593,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', @@ -1354,7 +1353,6 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', diff --git a/package.xml b/package.xml index 560b422d94d..7ced9e795f8 100644 --- a/package.xml +++ b/package.xml @@ -477,7 +477,6 @@ - @@ -811,7 +810,6 @@ - diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 0f04f14fd8a..86a9bb30cb4 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -522,6 +522,74 @@ static bool target_matches_localhost(const char* name) { return out; } +#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY +static bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during manual localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during manual localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} +#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ + +static bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { +#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +#else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ + return false; +#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ +} + static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 2cb7c9e53a5..cc977c06b25 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -87,14 +87,6 @@ void grpc_ares_complete_request_locked(grpc_ares_request* request); /* E.g., return false if ipv6 is known to not be available. */ bool grpc_ares_query_ipv6(); -/* Maybe (depending on the current platform) checks if "name" matches - * "localhost" and if so fills in addrs with the correct sockaddr structures. - * Returns a bool indicating whether or not such an action was performed. - * See https://github.com/grpc/grpc/issues/15158. */ -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs); - /* Sorts destinations in lb_addrs according to RFC 6724. */ void grpc_cares_wrapper_address_sorting_sort( grpc_core::ServerAddressList* addresses); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index eb0b3dab4a4..f85feb674dd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -25,7 +25,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -37,20 +36,4 @@ bool grpc_ares_query_ipv6() { return true; } -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { -#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; -#else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ - return false; -#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ -} - #endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 028d8442169..23c0fec74f3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -26,10 +26,4 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { - return false; -} - #endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index e48f9501752..06cd5722ce3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -25,7 +25,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -33,16 +32,4 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } -bool grpc_ares_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; -} - #endif /* GRPC_ARES == 1 && defined(GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc deleted file mode 100644 index 1331a6a67f5..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && defined(GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY) - -#include - -#include "src/core/ext/filters/client_channel/parse_address.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/gpr/string.h" - -bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during manual localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during manual localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; -} - -#endif /* GRPC_ARES == 1 && defined(GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h deleted file mode 100644 index 783b781154c..00000000000 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H - -#include - -#include - -#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" - -bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port); - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_WINDOWS_INNER_H \ - */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c9217aded63..2619ccf9740 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -385,7 +385,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', - 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc', 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 483e639be66..b34c7734621 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -951,8 +951,6 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallba src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc \ -src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index de08e38a838..39ee76b1a9c 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9178,8 +9178,7 @@ ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" ], "is_filegroup": true, "language": "c", @@ -9196,9 +9195,7 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows_inner.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" ], "third_party": false, "type": "filegroup" From beca35661a5f1b3e14db3dff7cb693bbaa92d600 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 14 May 2019 15:45:02 -0700 Subject: [PATCH 047/676] Move ifdefs around --- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 86a9bb30cb4..ad0f1460121 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -572,12 +572,10 @@ static bool inner_maybe_resolve_localhost_manually_locked( } return false; } -#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ static bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { -#ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY char* host = nullptr; char* port = nullptr; bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, @@ -585,10 +583,14 @@ static bool grpc_ares_maybe_resolve_localhost_manually_locked( gpr_free(host); gpr_free(port); return out; +} #else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ +static bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { return false; -#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ } +#endif /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, From 02069b48da048efbca2fb49d09108c4d5b62f027 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 15 May 2019 23:33:07 -0700 Subject: [PATCH 048/676] Remove get-grpc.sh --- .../grpc_interop_aspnetcore/build_interop.sh.template | 2 -- .../interoptest/grpc_interop_aspnetcore/build_interop.sh | 2 -- 2 files changed, 4 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index d64286ab03c..55ecfb30192 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -38,7 +38,5 @@ then ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet fi - - ./build/get-grpc.sh dotnet build --configuration Debug Grpc.AspNetCore.sln diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 65e848ded32..0b32638b54b 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -37,6 +37,4 @@ then ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet fi -./build/get-grpc.sh - dotnet build --configuration Debug Grpc.AspNetCore.sln From 39be72a230d4a89c7441220780edf41a8a76bb95 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 May 2019 08:46:45 -0700 Subject: [PATCH 049/676] Remove "class Channel" forward reference from generated code --- src/compiler/cpp_generator.cc | 1 - test/cpp/codegen/compiler_test_golden | 1 - 2 files changed, 2 deletions(-) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index ecec3206577..3380aeb257b 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -160,7 +160,6 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, printer->Print(vars, "class MessageAllocator;\n"); printer->Print(vars, "} // namespace experimental\n"); printer->Print(vars, "class CompletionQueue;\n"); - printer->Print(vars, "class Channel;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 9e99bc7b0a2..46efdf1603a 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -46,7 +46,6 @@ template class MessageAllocator; } // namespace experimental class CompletionQueue; -class Channel; class ServerCompletionQueue; class ServerContext; } // namespace grpc From 4b89514919cbf1bb62294400587f9d98af323284 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 15 May 2019 12:04:13 -0700 Subject: [PATCH 050/676] Fix default value compile issues --- src/core/lib/surface/completion_queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index f5b0822fcb4..16550ac61eb 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,7 +77,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal); + void* done_arg, grpc_cq_completion* storage, bool internal = false); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); From 51210ba9222a9e6a9e23523d7b9834b3c3810de1 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 10 May 2019 21:38:59 -0700 Subject: [PATCH 051/676] Update the message allocator API --- .../grpcpp/impl/codegen/message_allocator.h | 47 +++--- include/grpcpp/impl/codegen/server_callback.h | 101 ++++++------- .../end2end/message_allocator_end2end_test.cc | 139 ++++++++++-------- 3 files changed, 148 insertions(+), 139 deletions(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index 107bec62f1d..c3054313864 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -22,31 +22,42 @@ namespace grpc { namespace experimental { -// This is per rpc struct for the allocator. We can potentially put the grpc -// call arena in here in the future. +// NOTE: This is an API for advanced users who need custom allocators. +// Per rpc struct for the allocator. This is the interface to return to user. +class RpcAllocatorState { + public: + virtual ~RpcAllocatorState() = default; + // Optionally deallocate request early to reduce the size of working set. + // A custom MessageAllocator needs to be registered to make use of this. + // This is not abstract because implementing it is optional. + virtual void FreeRequest() {} +}; + +// This is the interface returned by the allocator. +// grpc library will call the methods to get request/response pointers and to +// release the object when it is done. template -struct RpcAllocatorInfo { - RequestT* request; - ResponseT* response; - // per rpc allocator internal state. MessageAllocator can set it when - // AllocateMessages is called and use it later. - void* allocator_state; +class MessageHolder : public RpcAllocatorState { + public: + virtual void Release() { delete this; } + RequestT* request() { return request_; } + ResponseT* response() { return response_; } + + protected: + // NOTE: subclasses should set these pointers. + RequestT* request_; + ResponseT* response_; }; -// Implementations need to be thread-safe +// A custom allocator can be set via the generated code to a callback unary +// method, such as SetMessageAllocatorFor_Echo(custom_allocator). The allocator +// needs to be alive for the lifetime of the server. +// Implementations need to be thread-safe. template class MessageAllocator { public: virtual ~MessageAllocator() = default; - // Allocate both request and response - virtual void AllocateMessages( - RpcAllocatorInfo* info) = 0; - // Optional: deallocate request early, called by - // ServerCallbackRpcController::ReleaseRequest - virtual void DeallocateRequest(RpcAllocatorInfo* info) {} - // Deallocate response and request (if applicable) - virtual void DeallocateMessages( - RpcAllocatorInfo* info) = 0; + virtual MessageHolder* AllocateMessages() = 0; }; } // namespace experimental diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 3f6d5cd3555..62cdd452308 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -77,6 +77,24 @@ class ServerReactor { std::atomic_int on_cancel_conditions_remaining_{2}; }; +template +class DefaultMessageHolder + : public experimental::MessageHolder { + public: + DefaultMessageHolder() { + this->request_ = &request_obj_; + this->response_ = &response_obj_; + } + void Release() override { + // the object is allocated in the call arena. + this->~DefaultMessageHolder(); + } + + private: + Request request_obj_; + Response response_obj_; +}; + } // namespace internal namespace experimental { @@ -137,13 +155,9 @@ class ServerCallbackRpcController { virtual void SetCancelCallback(std::function callback) = 0; virtual void ClearCancelCallback() = 0; - // NOTE: This is an API for advanced users who need custom allocators. - // Optionally deallocate request early to reduce the size of working set. - // A custom MessageAllocator needs to be registered to make use of this. - virtual void FreeRequest() = 0; // NOTE: This is an API for advanced users who need custom allocators. // Get and maybe mutate the allocator state associated with the current RPC. - virtual void* GetAllocatorState() = 0; + virtual RpcAllocatorState* GetRpcAllocatorState() = 0; }; // NOTE: The actual streaming object classes are provided @@ -465,13 +479,13 @@ class CallbackUnaryHandler : public MethodHandler { void RunHandler(const HandlerParameter& param) final { // Arena allocate a controller structure (that includes request/response) g_core_codegen_interface->grpc_call_ref(param.call->call()); - auto* allocator_info = - static_cast*>( + auto* allocator_state = + static_cast*>( param.internal_data); auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) ServerCallbackRpcControllerImpl(param.server_context, param.call, - allocator_info, allocator_, + allocator_state, std::move(param.call_requester)); Status status = param.status; if (status.ok()) { @@ -489,36 +503,24 @@ class CallbackUnaryHandler : public MethodHandler { ByteBuffer buf; buf.set_buffer(req); RequestType* request = nullptr; - experimental::RpcAllocatorInfo* allocator_info = - new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(*allocator_info))) - experimental::RpcAllocatorInfo(); + experimental::MessageHolder* allocator_state = + nullptr; if (allocator_ != nullptr) { - allocator_->AllocateMessages(allocator_info); + allocator_state = allocator_->AllocateMessages(); } else { - allocator_info->request = - new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(RequestType))) RequestType(); - allocator_info->response = - new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(ResponseType))) ResponseType(); + allocator_state = new (g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(DefaultMessageHolder))) + DefaultMessageHolder(); } - *handler_data = allocator_info; - request = allocator_info->request; + *handler_data = allocator_state; + request = allocator_state->request(); *status = SerializationTraits::Deserialize(&buf, request); buf.Release(); if (status->ok()) { return request; } // Clean up on deserialization failure. - if (allocator_ != nullptr) { - allocator_->DeallocateMessages(allocator_info); - } else { - allocator_info->request->~RequestType(); - allocator_info->response->~ResponseType(); - allocator_info->request = nullptr; - allocator_info->response = nullptr; - } + allocator_state->Release(); return nullptr; } @@ -548,9 +550,8 @@ class CallbackUnaryHandler : public MethodHandler { } // The response is dropped if the status is not OK. if (s.ok()) { - finish_ops_.ServerSendStatus( - &ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(allocator_info_->response)); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(response())); } else { finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); } @@ -588,14 +589,8 @@ class CallbackUnaryHandler : public MethodHandler { void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } - void FreeRequest() override { - if (allocator_ != nullptr) { - allocator_->DeallocateRequest(allocator_info_); - } - } - - void* GetAllocatorState() override { - return allocator_info_->allocator_state; + experimental::RpcAllocatorState* GetRpcAllocatorState() override { + return allocator_state_; } private: @@ -603,35 +598,23 @@ class CallbackUnaryHandler : public MethodHandler { ServerCallbackRpcControllerImpl( ServerContext* ctx, Call* call, - experimental::RpcAllocatorInfo* - allocator_info, - experimental::MessageAllocator* allocator, + experimental::MessageHolder* allocator_state, std::function call_requester) : ctx_(ctx), call_(*call), - allocator_info_(allocator_info), - allocator_(allocator), + allocator_state_(allocator_state), call_requester_(std::move(call_requester)) { ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); } - const RequestType* request() { return allocator_info_->request; } - ResponseType* response() { return allocator_info_->response; } + const RequestType* request() { return allocator_state_->request(); } + ResponseType* response() { return allocator_state_->response(); } void MaybeDone() { if (--callbacks_outstanding_ == 0) { grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); - if (allocator_ != nullptr) { - allocator_->DeallocateMessages(allocator_info_); - } else { - if (allocator_info_->request != nullptr) { - allocator_info_->request->~RequestType(); - } - if (allocator_info_->response != nullptr) { - allocator_info_->response->~ResponseType(); - } - } + allocator_state_->Release(); this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor g_core_codegen_interface->grpc_call_unref(call); call_requester(); @@ -647,8 +630,8 @@ class CallbackUnaryHandler : public MethodHandler { ServerContext* ctx_; Call call_; - experimental::RpcAllocatorInfo* allocator_info_; - experimental::MessageAllocator* allocator_; + experimental::MessageHolder* const + allocator_state_; std::function call_requester_; std::atomic_int callbacks_outstanding_{ 2}; // reserve for Finish and CompletionOp diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index c833a4ff1b6..b4ed1d47f8f 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -25,6 +25,7 @@ #include +#include #include #include @@ -62,11 +63,9 @@ class CallbackTestServiceImpl public: explicit CallbackTestServiceImpl() {} - void SetFreeRequest() { free_request_ = true; } - void SetAllocatorMutator( - std::function + std::function mutator) { allocator_mutator_ = mutator; } @@ -75,18 +74,15 @@ class CallbackTestServiceImpl EchoResponse* response, experimental::ServerCallbackRpcController* controller) override { response->set_message(request->message()); - if (free_request_) { - controller->FreeRequest(); - } else if (allocator_mutator_) { - allocator_mutator_(controller->GetAllocatorState(), request, response); + if (allocator_mutator_) { + allocator_mutator_(controller->GetRpcAllocatorState(), request, response); } controller->Finish(Status::OK); } private: - bool free_request_ = false; - std::function + std::function allocator_mutator_; }; @@ -230,26 +226,44 @@ class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { class SimpleAllocator : public experimental::MessageAllocator { public: - void AllocateMessages( - experimental::RpcAllocatorInfo* info) { + class MessageHolderImpl + : public experimental::MessageHolder { + public: + MessageHolderImpl(int* request_deallocation_count, + int* messages_deallocation_count) + : request_deallocation_count_(request_deallocation_count), + messages_deallocation_count_(messages_deallocation_count) { + request_ = new EchoRequest; + response_ = new EchoResponse; + } + void Release() override { + (*messages_deallocation_count_)++; + delete request_; + delete response_; + delete this; + } + void FreeRequest() override { + (*request_deallocation_count_)++; + delete request_; + request_ = nullptr; + } + + EchoRequest* ReleaseRequest() { + auto* ret = request_; + request_ = nullptr; + return ret; + } + + private: + int* request_deallocation_count_; + int* messages_deallocation_count_; + }; + experimental::MessageHolder* AllocateMessages() + override { allocation_count++; - info->request = new EchoRequest; - info->response = new EchoResponse; - info->allocator_state = info; - } - void DeallocateRequest( - experimental::RpcAllocatorInfo* info) { - request_deallocation_count++; - delete info->request; - info->request = nullptr; - } - void DeallocateMessages( - experimental::RpcAllocatorInfo* info) { - messages_deallocation_count++; - delete info->request; - delete info->response; + return new MessageHolderImpl(&request_deallocation_count, + &messages_deallocation_count); } - int allocation_count = 0; int request_deallocation_count = 0; int messages_deallocation_count = 0; @@ -272,7 +286,16 @@ TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { MAYBE_SKIP_TEST; const int kRpcCount = 10; std::unique_ptr allocator(new SimpleAllocator); - callback_service_.SetFreeRequest(); + auto mutator = [](experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp) { + auto* info = + static_cast(allocator_state); + EXPECT_EQ(req, info->request()); + EXPECT_EQ(resp, info->response()); + allocator_state->FreeRequest(); + EXPECT_EQ(nullptr, info->request()); + }; + callback_service_.SetAllocatorMutator(mutator); CreateServer(allocator.get()); ResetStub(); SendRpcs(kRpcCount); @@ -286,17 +309,15 @@ TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { const int kRpcCount = 10; std::unique_ptr allocator(new SimpleAllocator); std::vector released_requests; - auto mutator = [&released_requests](void* allocator_state, - const EchoRequest* req, - EchoResponse* resp) { + auto mutator = [&released_requests]( + experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp) { auto* info = - static_cast*>( - allocator_state); - EXPECT_EQ(req, info->request); - EXPECT_EQ(resp, info->response); - EXPECT_EQ(allocator_state, info->allocator_state); - released_requests.push_back(info->request); - info->request = nullptr; + static_cast(allocator_state); + EXPECT_EQ(req, info->request()); + EXPECT_EQ(resp, info->response()); + released_requests.push_back(info->ReleaseRequest()); + EXPECT_EQ(nullptr, info->request()); }; callback_service_.SetAllocatorMutator(mutator); CreateServer(allocator.get()); @@ -316,30 +337,25 @@ class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { class ArenaAllocator : public experimental::MessageAllocator { public: - void AllocateMessages( - experimental::RpcAllocatorInfo* info) { + class MessageHolderImpl + : public experimental::MessageHolder { + public: + MessageHolderImpl() { + request_ = google::protobuf::Arena::CreateMessage(&arena_); + response_ = + google::protobuf::Arena::CreateMessage(&arena_); + } + void FreeRequest() override { GPR_ASSERT(0); } + + private: + google::protobuf::Arena arena_; + }; + experimental::MessageHolder* AllocateMessages() + override { allocation_count++; - auto* arena = new google::protobuf::Arena; - info->allocator_state = arena; - info->request = - google::protobuf::Arena::CreateMessage(arena); - info->response = - google::protobuf::Arena::CreateMessage(arena); - } - void DeallocateRequest( - experimental::RpcAllocatorInfo* info) { - GPR_ASSERT(0); + return new MessageHolderImpl; } - void DeallocateMessages( - experimental::RpcAllocatorInfo* info) { - deallocation_count++; - auto* arena = - static_cast(info->allocator_state); - delete arena; - } - int allocation_count = 0; - int deallocation_count = 0; }; }; @@ -351,7 +367,6 @@ TEST_P(ArenaAllocatorTest, SimpleRpc) { ResetStub(); SendRpcs(kRpcCount); EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->deallocation_count); } std::vector CreateTestScenarios(bool test_insecure) { From 7c5bfbbb3237a9a662be6b1c9f5dcb3112a25922 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 14 May 2019 15:37:10 -0700 Subject: [PATCH 052/676] Resolve comments --- .../grpcpp/impl/codegen/message_allocator.h | 4 +++- include/grpcpp/impl/codegen/server_callback.h | 4 ++-- .../end2end/message_allocator_end2end_test.cc | 23 ++++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index c3054313864..422f8c2ea21 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -42,8 +42,10 @@ class MessageHolder : public RpcAllocatorState { virtual void Release() { delete this; } RequestT* request() { return request_; } ResponseT* response() { return response_; } + void set_request(RequestT* request) { request_ = request; } + void set_response(ResponseT* response) { response_ = response; } - protected: + private: // NOTE: subclasses should set these pointers. RequestT* request_; ResponseT* response_; diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 62cdd452308..9254518b605 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -82,8 +82,8 @@ class DefaultMessageHolder : public experimental::MessageHolder { public: DefaultMessageHolder() { - this->request_ = &request_obj_; - this->response_ = &response_obj_; + this->set_request(&request_obj_); + this->set_response(&response_obj_); } void Release() override { // the object is allocated in the call arena. diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index b4ed1d47f8f..2abe26fe825 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -233,24 +233,24 @@ class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { int* messages_deallocation_count) : request_deallocation_count_(request_deallocation_count), messages_deallocation_count_(messages_deallocation_count) { - request_ = new EchoRequest; - response_ = new EchoResponse; + set_request(new EchoRequest); + set_response(new EchoResponse); } void Release() override { (*messages_deallocation_count_)++; - delete request_; - delete response_; + delete request(); + delete response(); delete this; } void FreeRequest() override { (*request_deallocation_count_)++; - delete request_; - request_ = nullptr; + delete request(); + set_request(nullptr); } EchoRequest* ReleaseRequest() { - auto* ret = request_; - request_ = nullptr; + auto* ret = request(); + set_request(nullptr); return ret; } @@ -341,9 +341,10 @@ class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { : public experimental::MessageHolder { public: MessageHolderImpl() { - request_ = google::protobuf::Arena::CreateMessage(&arena_); - response_ = - google::protobuf::Arena::CreateMessage(&arena_); + set_request( + google::protobuf::Arena::CreateMessage(&arena_)); + set_response( + google::protobuf::Arena::CreateMessage(&arena_)); } void FreeRequest() override { GPR_ASSERT(0); } From 26ba981deeda821fae3a185b21308d16adcbbfe4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 16 May 2019 09:34:20 -0700 Subject: [PATCH 053/676] Fix clang errors --- src/core/lib/surface/completion_queue.cc | 68 +++++++++++------------- src/core/lib/surface/completion_queue.h | 3 +- 2 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index d040e91b796..f1b31e9cbba 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -355,23 +355,20 @@ static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); // queue. The done argument is a callback that will be invoked when it is // safe to free up that storage. The storage MUST NOT be freed until the // done callback is invoked. -static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal = false); - -static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal = false); - -static void cq_end_op_for_callback(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal = false); +static void cq_end_op_for_next( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal = false); + +static void cq_end_op_for_pluck( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal = false); + +static void cq_end_op_for_callback( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal = false); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -675,12 +672,10 @@ bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_NEXT) */ -static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal) { +static void cq_end_op_for_next( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -756,12 +751,10 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_PLUCK) */ -static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal) { +static void cq_end_op_for_pluck( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -833,8 +826,7 @@ static void functor_callback(void* arg, grpc_error* error) { static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, - bool internal) { + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -866,13 +858,14 @@ static void cq_end_op_for_callback( auto* functor = static_cast(tag); if (internal) { - grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, + (error == GRPC_ERROR_NONE)); } else { GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); @@ -880,7 +873,8 @@ static void cq_end_op_for_callback( void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal) { + void* done_arg, grpc_cq_completion* storage, + bool internal) { cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); } diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 16550ac61eb..3ba9fbb8765 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,7 +77,8 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal = false); + void* done_arg, grpc_cq_completion* storage, + bool internal = false); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); From 1d5357d1bbfd1e83bad7f5b02c1b4937bdc9b61f Mon Sep 17 00:00:00 2001 From: ZhouyihaiDing Date: Thu, 16 May 2019 09:55:18 -0700 Subject: [PATCH 054/676] Change persistent log to gpr_log --- src/php/ext/grpc/channel.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index c06bdea7feb..860d38be34a 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -30,6 +30,7 @@ #include #include +#include #include "completion_queue.h" #include "channel_credentials.h" @@ -247,12 +248,12 @@ void create_and_add_channel_to_persistent_list( // If no channel can be deleted from the persistent map, // do not persist this one. create_channel(channel, target, args, creds); - php_printf("[Warning] The number of channel for the" + gpr_log(GPR_INFO, "[Warning] The number of channel for the" " target %s is maxed out bounded.\n", target); - php_printf("[Warning] Target upper bound: %d. Current size: %d.\n", + gpr_log(GPR_INFO, "[Warning] Target upper bound: %d. Current size: %d.\n", target_bound_status->upper_bound, target_bound_status->current_count); - php_printf("[Warning] Target %s will not be persisted.\n", target); + gpr_log(GPR_INFO, "[Warning] Target %s will not be persisted.\n", target); return; } } From 1bc44a1a5a54dba6b02159d79fbd5c8680935694 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 9 May 2019 16:54:22 -0700 Subject: [PATCH 055/676] Fix node interop build scripts --- .../interoptest/grpc_interop_node/build_interop.sh | 4 +--- .../interoptest/grpc_interop_nodepurejs/build_interop.sh | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh index c16efc1d354..aeb82e0c9c3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh @@ -29,6 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g node-gyp gulp -npm install -gulp setup +./setup_interop.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh index d41ccacd2f9..db55f5a19f3 100755 --- a/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_nodepurejs/build_interop.sh @@ -29,8 +29,4 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-node # build Node interop client & server -npm install -g gulp -npm install -gulp js.core.install -gulp protobuf.install -gulp internal.test.install +./setup_interop_purejs.sh From 40210d3b8a92a285d174322ee9f1e823d619cec3 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 16 May 2019 22:31:12 -0700 Subject: [PATCH 056/676] Move Channel to grpc_impl --- BUILD | 1 + BUILD.gn | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/channel.h | 85 +--- include/grpcpp/channel_impl.h | 125 ++++++ include/grpcpp/impl/codegen/client_callback.h | 5 +- include/grpcpp/impl/codegen/client_context.h | 11 +- .../grpcpp/impl/codegen/client_interceptor.h | 6 +- .../grpcpp/impl/codegen/completion_queue.h | 372 +----------------- .../grpcpp/impl/codegen/server_interface.h | 4 +- include/grpcpp/security/credentials_impl.h | 1 + include/grpcpp/server_builder_impl.h | 2 - include/grpcpp/server_impl.h | 5 +- src/cpp/client/channel_cc.cc | 61 +-- src/cpp/client/client_context.cc | 9 +- src/cpp/client/create_channel.cc | 2 +- src/cpp/client/create_channel_internal.cc | 4 +- src/cpp/client/create_channel_internal.h | 4 +- src/cpp/client/create_channel_posix.cc | 6 +- src/cpp/client/secure_credentials.h | 2 + test/cpp/codegen/golden_file_test.cc | 2 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- test/cpp/util/create_test_channel.h | 18 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 30 files changed, 229 insertions(+), 513 deletions(-) create mode 100644 include/grpcpp/channel_impl.h diff --git a/BUILD b/BUILD index 52c469f0b4a..da5439648d4 100644 --- a/BUILD +++ b/BUILD @@ -218,6 +218,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", diff --git a/BUILD.gn b/BUILD.gn index ea5d544972f..8ea6eeeced0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1022,6 +1022,7 @@ config("grpc_config") { "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f85bff572e6..4e79f073a5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3150,6 +3150,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -3765,6 +3766,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -4752,6 +4754,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h diff --git a/Makefile b/Makefile index 9cf0ab03f09..4bcc6417816 100644 --- a/Makefile +++ b/Makefile @@ -5507,6 +5507,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -6130,6 +6131,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -7066,6 +7068,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/build.yaml b/build.yaml index fbfa0df86cd..0364be34caa 100644 --- a/build.yaml +++ b/build.yaml @@ -1350,6 +1350,7 @@ filegroups: - include/grpcpp/alarm.h - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h + - include/grpcpp/channel_impl.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 57743df8c7c..a62b9c84a63 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -82,6 +82,7 @@ Pod::Spec.new do |s| ss.source_files = 'include/grpcpp/alarm.h', 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', + 'include/grpcpp/channel_impl.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index b3c4703d9d5..163c804ffbe 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -19,22 +19,12 @@ #ifndef GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_channel; +#include namespace grpc { +typedef ::grpc_impl::Channel Channel; + namespace experimental { /// Resets the channel's connection backoff. /// TODO(roth): Once we see whether this proves useful, either create a gRFC @@ -42,75 +32,6 @@ namespace experimental { void ChannelResetConnectionBackoff(Channel* channel); } // namespace experimental -/// Channels represent a connection to an endpoint. Created by \a CreateChannel. -class Channel final : public ChannelInterface, - public internal::CallHook, - public std::enable_shared_from_this, - private GrpcLibraryCodegen { - public: - ~Channel(); - - /// Get the current channel state. If the channel is in IDLE and - /// \a try_to_connect is set to true, try to connect. - grpc_connectivity_state GetState(bool try_to_connect) override; - - /// Returns the LB policy name, or the empty string if not yet available. - grpc::string GetLoadBalancingPolicyName() const; - - /// Returns the service config in JSON form, or the empty string if - /// not available. - grpc::string GetServiceConfigJSON() const; - - private: - template - friend class internal::BlockingUnaryCallImpl; - friend void experimental::ChannelResetConnectionBackoff(Channel* channel); - friend std::shared_ptr CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel, - std::vector> - interceptor_creators); - friend class internal::InterceptedChannel; - Channel(const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> - interceptor_creators); - - internal::Call CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) override; - void PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) override; - void* RegisterMethod(const char* method) override; - - void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, - void* tag) override; - bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline) override; - - CompletionQueue* CallbackCQ() override; - - internal::Call CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, CompletionQueue* cq, - size_t interceptor_pos) override; - - const grpc::string host_; - grpc_channel* const c_channel_; // owned - - // mu_ protects callback_cq_ (the per-channel callbackable completion queue) - grpc::internal::Mutex mu_; - - // callback_cq_ references the callbackable completion queue associated - // with this channel (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the channel; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - CompletionQueue* callback_cq_ = nullptr; - - std::vector> - interceptor_creators_; -}; - } // namespace grpc #endif // GRPCPP_CHANNEL_H diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h new file mode 100644 index 00000000000..39917d2eb74 --- /dev/null +++ b/include/grpcpp/channel_impl.h @@ -0,0 +1,125 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_CHANNEL_IMPL_H +#define GRPCPP_CHANNEL_IMPL_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_channel; + +namespace grpc { + +std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr> + interceptor_creators); +} // namespace grpc +namespace grpc_impl { + +namespace experimental { +/// Resets the channel's connection backoff. +/// TODO(roth): Once we see whether this proves useful, either create a gRFC +/// and change this to be a method of the Channel class, or remove it. +void ChannelResetConnectionBackoff(Channel* channel); +} // namespace experimental + +/// Channels represent a connection to an endpoint. Created by \a CreateChannel. +class Channel final : public ::grpc::ChannelInterface, + public ::grpc::internal::CallHook, + public std::enable_shared_from_this, + private ::grpc::GrpcLibraryCodegen { + public: + ~Channel(); + + /// Get the current channel state. If the channel is in IDLE and + /// \a try_to_connect is set to true, try to connect. + grpc_connectivity_state GetState(bool try_to_connect) override; + + /// Returns the LB policy name, or the empty string if not yet available. + grpc::string GetLoadBalancingPolicyName() const; + + /// Returns the service config in JSON form, or the empty string if + /// not available. + grpc::string GetServiceConfigJSON() const; + + private: + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + friend void experimental::ChannelResetConnectionBackoff(Channel* channel); + friend std::shared_ptr grpc::CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector> + interceptor_creators); + friend class ::grpc::internal::InterceptedChannel; + Channel(const grpc::string& host, grpc_channel* c_channel, + std::vector> + interceptor_creators); + + ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) override; + void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) override; + void* RegisterMethod(const char* method) override; + + void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline, + ::grpc::CompletionQueue* cq, void* tag) override; + bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline) override; + + ::grpc::CompletionQueue* CallbackCQ() override; + + ::grpc::internal::Call CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; + + const grpc::string host_; + grpc_channel* const c_channel_; // owned + + // mu_ protects callback_cq_ (the per-channel callbackable completion queue) + grpc::internal::Mutex mu_; + + // callback_cq_ references the callbackable completion queue associated + // with this channel (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the channel; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + ::grpc::CompletionQueue* callback_cq_ = nullptr; + + std::vector< + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + interceptor_creators_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_CHANNEL_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index c897f6676d9..f0499858a05 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -29,9 +29,12 @@ #include #include +namespace grpc_impl { +class Channel; +} + namespace grpc { -class Channel; class ClientContext; class CompletionQueue; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 355ac557b3a..999d8fcbfe7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -60,12 +60,12 @@ struct grpc_call; namespace grpc_impl { class CallCredentials; +class Channel; +class CompletionQueue; } // namespace grpc_impl namespace grpc { -class Channel; class ChannelInterface; -class CompletionQueue; class ClientContext; namespace internal { @@ -397,7 +397,7 @@ class ClientContext { friend class ::grpc::testing::InteropClientContextInspector; friend class ::grpc::internal::CallOpClientRecvStatus; friend class ::grpc::internal::CallOpRecvInitialMetadata; - friend class Channel; + friend class ::grpc_impl::Channel; template friend class ::grpc::ClientReader; template @@ -430,7 +430,8 @@ class ClientContext { } grpc_call* call() const { return call_; } - void set_call(grpc_call* call, const std::shared_ptr& channel); + void set_call(grpc_call* call, + const std::shared_ptr<::grpc_impl::Channel>& channel); experimental::ClientRpcInfo* set_client_rpc_info( const char* method, internal::RpcMethod::RpcType type, @@ -463,7 +464,7 @@ class ClientContext { bool wait_for_ready_explicitly_set_; bool idempotent_; bool cacheable_; - std::shared_ptr channel_; + std::shared_ptr<::grpc_impl::Channel> channel_; grpc::internal::Mutex mu_; grpc_call* call_; bool call_canceled_; diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 19106545089..a4c85a76da5 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -26,10 +26,14 @@ #include #include +namespace grpc_impl { + +class Channel; +} + namespace grpc { class ClientContext; -class Channel; namespace internal { class InterceptorBatchMethodsImpl; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 5afff52bfb1..472d95504dc 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -39,378 +39,10 @@ #include #include -struct grpc_completion_queue; - -namespace grpc_impl { - -class Server; -class ServerBuilder; -} // namespace grpc_impl namespace grpc { -template -class ClientReader; -template -class ClientWriter; -template -class ClientReaderWriter; -template -class ServerReader; -template -class ServerWriter; -namespace internal { -template -class ServerReaderWriterBody; -} // namespace internal - -class Channel; -class ChannelInterface; -class ClientContext; -class CompletionQueue; -class ServerContext; -class ServerInterface; - -namespace internal { -class CompletionQueueTag; -class RpcMethod; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; -template -class BidiStreamingHandler; -template -class TemplatedBidiStreamingHandler; -template -class ErrorMethodHandler; -template -class BlockingUnaryCallImpl; -template -class CallOpSet; -} // namespace internal - -extern CoreCodegenInterface* g_core_codegen_interface; - -/// A thin wrapper around \ref grpc_completion_queue (see \ref -/// src/core/lib/surface/completion_queue.h). -/// See \ref doc/cpp/perf_notes.md for notes on best practices for high -/// performance servers. -class CompletionQueue : private GrpcLibraryCodegen { - public: - /// Default constructor. Implicitly creates a \a grpc_completion_queue - /// instance. - CompletionQueue() - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, - nullptr}) {} - - /// Wrap \a take, taking ownership of the instance. - /// - /// \param take The completion queue instance to wrap. Ownership is taken. - explicit CompletionQueue(grpc_completion_queue* take); - - /// Destructor. Destroys the owned wrapped completion queue / instance. - ~CompletionQueue() { - g_core_codegen_interface->grpc_completion_queue_destroy(cq_); - } - - /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. - enum NextStatus { - SHUTDOWN, ///< The completion queue has been shutdown and fully-drained - GOT_EVENT, ///< Got a new event; \a tag will be filled in with its - ///< associated value; \a ok indicating its success. - TIMEOUT ///< deadline was reached. - }; - - /// Read from the queue, blocking until an event is available or the queue is - /// shutting down. - /// - /// \param tag [out] Updated to point to the read event's tag. - /// \param ok [out] true if read a successful event, false otherwise. - /// - /// Note that each tag sent to the completion queue (through RPC operations - /// or alarms) will be delivered out of the completion queue by a call to - /// Next (or a related method), regardless of whether the operation succeeded - /// or not. Success here means that this operation completed in the normal - /// valid manner. - /// - /// Server-side RPC request: \a ok indicates that the RPC has indeed - /// been started. If it is false, the server has been Shutdown - /// before this particular call got matched to an incoming RPC. - /// - /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is - /// going to go to the wire. If it is false, it not going to the wire. This - /// would happen if the channel is either permanently broken or - /// transiently broken but with the fail-fast option. (Note that async unary - /// RPCs don't post a CQ tag at this point, nor do client-streaming - /// or bidi-streaming RPCs that have the initial metadata corked option set.) - /// - /// Client-side Write, Client-side WritesDone, Server-side Write, - /// Server-side Finish, Server-side SendInitialMetadata (which is - /// typically included in Write or Finish when not done explicitly): - /// \a ok means that the data/metadata/status/etc is going to go to the - /// wire. If it is false, it not going to the wire because the call - /// is already dead (i.e., canceled, deadline expired, other side - /// dropped the channel, etc). - /// - /// Client-side Read, Server-side Read, Client-side - /// RecvInitialMetadata (which is typically included in Read if not - /// done explicitly): \a ok indicates whether there is a valid message - /// that got read. If not, you know that there are certainly no more - /// messages that can ever be read from this stream. For the client-side - /// operations, this only happens because the call is dead. For the - /// server-sider operation, though, this could happen because the client - /// has done a WritesDone already. - /// - /// Client-side Finish: \a ok should always be true - /// - /// Server-side AsyncNotifyWhenDone: \a ok should always be true - /// - /// Alarm: \a ok is true if it expired, false if it was canceled - /// - /// \return true if got an event, false if the queue is fully drained and - /// shut down. - bool Next(void** tag, bool* ok) { - return (AsyncNextInternal(tag, ok, - g_core_codegen_interface->gpr_inf_future( - GPR_CLOCK_REALTIME)) != SHUTDOWN); - } - - /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param tag [out] Upon success, updated to point to the event's tag. - /// \param ok [out] Upon success, true if a successful event, false otherwise - /// See documentation for CompletionQueue::Next for explanation of ok - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { - TimePoint deadline_tp(deadline); - return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); - } - - /// EXPERIMENTAL - /// First executes \a F, then reads from the queue, blocking up to - /// \a deadline (or the queue's shutdown). - /// Both \a tag and \a ok are updated upon success (if an event is available - /// within the \a deadline). A \a tag points to an arbitrary location usually - /// employed to uniquely identify an event. - /// - /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon success, updated to point to the event's tag. - /// \param ok [out] Upon success, true if read a regular event, false - /// otherwise. - /// \param deadline [in] How long to block in wait for an event. - /// - /// \return The type of event read. - template - NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { - CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); - f(); - if (cache.Flush(tag, ok)) { - return GOT_EVENT; - } else { - return AsyncNext(tag, ok, deadline); - } - } - - /// Request the shutdown of the queue. - /// - /// \warning This method must be called at some point if this completion queue - /// is accessed with Next or AsyncNext. \a Next will not return false - /// until this method has been called and all pending tags have been drained. - /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) - /// Only once either one of these methods does that (that is, once the queue - /// has been \em drained) can an instance of this class be destroyed. - /// Also note that applications must ensure that no work is enqueued on this - /// completion queue after this method is called. - void Shutdown(); - - /// Returns a \em raw pointer to the underlying \a grpc_completion_queue - /// instance. - /// - /// \warning Remember that the returned instance is owned. No transfer of - /// owership is performed. - grpc_completion_queue* cq() { return cq_; } - - protected: - /// Private constructor of CompletionQueue only visible to friend classes - CompletionQueue(const grpc_completion_queue_attributes& attributes) { - cq_ = g_core_codegen_interface->grpc_completion_queue_create( - g_core_codegen_interface->grpc_completion_queue_factory_lookup( - &attributes), - &attributes, NULL); - InitialAvalanching(); // reserve this for the future shutdown - } - - private: - // Friend synchronous wrappers so that they can access Pluck(), which is - // a semi-private API geared towards the synchronous implementation. - template - friend class ::grpc::ClientReader; - template - friend class ::grpc::ClientWriter; - template - friend class ::grpc::ClientReaderWriter; - template - friend class ::grpc::ServerReader; - template - friend class ::grpc::ServerWriter; - template - friend class ::grpc::internal::ServerReaderWriterBody; - template - friend class ::grpc::internal::RpcMethodHandler; - template - friend class ::grpc::internal::ClientStreamingHandler; - template - friend class ::grpc::internal::ServerStreamingHandler; - template - friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template - friend class ::grpc::internal::ErrorMethodHandler; - friend class ::grpc_impl::Server; - friend class ::grpc::ServerContext; - friend class ::grpc::ServerInterface; - template - friend class ::grpc::internal::BlockingUnaryCallImpl; - - // Friends that need access to constructor for callback CQ - friend class ::grpc::Channel; - - // For access to Register/CompleteAvalanching - template - friend class ::grpc::internal::CallOpSet; - - /// EXPERIMENTAL - /// Creates a Thread Local cache to store the first event - /// On this completion queue queued from this thread. Once - /// initialized, it must be flushed on the same thread. - class CompletionQueueTLSCache { - public: - CompletionQueueTLSCache(CompletionQueue* cq); - ~CompletionQueueTLSCache(); - bool Flush(void** tag, bool* ok); - - private: - CompletionQueue* cq_; - bool flushed_; - }; - - NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); - - /// Wraps \a grpc_completion_queue_pluck. - /// \warning Must not be mixed with calls to \a Next. - bool Pluck(internal::CompletionQueueTag* tag) { - auto deadline = - g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); - while (true) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - bool ok = ev.success != 0; - void* ignored = tag; - if (tag->FinalizeResult(&ignored, &ok)) { - GPR_CODEGEN_ASSERT(ignored == tag); - return ok; - } - } - } - - /// Performs a single polling pluck on \a tag. - /// \warning Must not be mixed with calls to \a Next. - /// - /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already - /// shutdown. This is most likely a bug and if it is a bug, then change this - /// implementation to simple call the other TryPluck function with a zero - /// timeout. i.e: - /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) - void TryPluck(internal::CompletionQueueTag* tag) { - auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT) return; - bool ok = ev.success != 0; - void* ignored = tag; - // the tag must be swallowed if using TryPluck - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if - /// the pluck() was successful and returned the tag. - /// - /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects - /// that the tag is internal not something that is returned to the user. - void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) { - auto ev = g_core_codegen_interface->grpc_completion_queue_pluck( - cq_, tag, deadline, nullptr); - if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { - return; - } - - bool ok = ev.success != 0; - void* ignored = tag; - GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); - } - - /// Manage state of avalanching operations : completion queue tags that - /// trigger other completion queue operations. The underlying core completion - /// queue should not really shutdown until all avalanching operations have - /// been finalized. Note that we maintain the requirement that an avalanche - /// registration must take place before CQ shutdown (which must be maintained - /// elsewhere) - void InitialAvalanching() { - gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); - } - void RegisterAvalanching() { - gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(1)); - } - void CompleteAvalanching() { - if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(-1)) == 1) { - g_core_codegen_interface->grpc_completion_queue_shutdown(cq_); - } - } - - grpc_completion_queue* cq_; // owned - - gpr_atm avalanches_in_flight_; -}; - -/// A specific type of completion queue used by the processing of notifications -/// by servers. Instantiated by \a ServerBuilder. -class ServerCompletionQueue : public CompletionQueue { - public: - bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } - - protected: - /// Default constructor - ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} - - private: - /// \param completion_type indicates whether this is a NEXT or CALLBACK - /// completion queue. - /// \param polling_type Informs the GRPC library about the type of polling - /// allowed on this completion queue. See grpc_cq_polling_type's description - /// in grpc_types.h for more details. - /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues - ServerCompletionQueue(grpc_cq_completion_type completion_type, - grpc_cq_polling_type polling_type, - grpc_experimental_completion_queue_functor* shutdown_cb) - : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, - shutdown_cb}), - polling_type_(polling_type) {} - - grpc_cq_polling_type polling_type_; - friend class grpc_impl::ServerBuilder; - friend class grpc_impl::Server; -}; +typedef ::grpc_impl::CompletionQueue CompletionQueue; +typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index ebad4eb25e1..26e997bfb56 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -30,12 +30,14 @@ namespace grpc_impl { +class Channel; +class CompletionQueue; +class ServerCompletionQueue; class ServerCredentials; } // namespace grpc_impl namespace grpc { class AsyncGenericService; -class Channel; class GenericServerContext; class ServerCompletionQueue; class ServerContext; diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index dec60b11eb4..29ba2075c29 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 0551862d38f..7c197a52f09 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -45,8 +45,6 @@ class ServerCredentials; namespace grpc { class AsyncGenericService; -class CompletionQueue; -class ServerCompletionQueue; class Service; namespace testing { class ServerBuilderPluginTest; diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 035c22136e4..59a780276e0 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -107,7 +108,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { } /// Establish a channel for in-process communication - std::shared_ptr InProcessChannel( + std::shared_ptr<::grpc::Channel> InProcessChannel( const grpc::ChannelArguments& args); /// NOTE: class experimental_type is not part of the public API of this class. @@ -119,7 +120,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// Establish a channel for in-process communication with client /// interceptors - std::shared_ptr InProcessChannelWithInterceptors( + std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors( const grpc::ChannelArguments& args, std::vector> diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 5812e96771f..f0aa8e4017a 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -42,14 +42,17 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/completion_queue.h" -namespace grpc { - -static internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel( - const grpc::string& host, grpc_channel* channel, - std::vector< - std::unique_ptr> - interceptor_creators) +void ::grpc::experimental::ChannelResetConnectionBackoff(Channel* channel) { + grpc_impl::experimental::ChannelResetConnectionBackoff(channel); +} + +namespace grpc_impl { + +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; +Channel::Channel(const grpc::string& host, grpc_channel* channel, + std::vector> + interceptor_creators) : host_(host), c_channel_(channel) { interceptor_creators_ = std::move(interceptor_creators); g_gli_initializer.summon(); @@ -65,7 +68,8 @@ Channel::~Channel() { namespace { inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); + return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, + len); } grpc::string GetChannelInfoField(grpc_channel* channel, @@ -103,10 +107,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq, - size_t interceptor_pos) { +::grpc::internal::Call Channel::CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) { const bool kRegistered = method.channel_tag() && context->authority().empty(); grpc_call* c_call = nullptr; if (kRegistered) { @@ -115,7 +118,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, context->propagation_options_.c_bitmask(), cq->cq(), method.channel_tag(), context->raw_deadline(), nullptr); } else { - const string* host_str = nullptr; + const ::grpc::string* host_str = nullptr; if (!context->authority_.empty()) { host_str = &context->authority_; } else if (!host_.empty()) { @@ -125,7 +128,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = SliceFromCopiedString(*host_str); + host_slice = ::grpc::SliceFromCopiedString(*host_str); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, @@ -147,17 +150,17 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, interceptor_creators_, interceptor_pos); context->set_call(c_call, shared_from_this()); - return internal::Call(c_call, this, cq, info); + return ::grpc::internal::Call(c_call, this, cq, info); } -::grpc::internal::Call Channel::CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) { +::grpc::internal::Call Channel::CreateCall( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + CompletionQueue* cq) { return CreateCallInternal(method, context, cq, 0); } -void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { +void Channel::PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) { ops->FillOps( call); // Make a copy of call. It's fine since Call just has pointers } @@ -173,7 +176,7 @@ grpc_connectivity_state Channel::GetState(bool try_to_connect) { namespace { -class TagSaver final : public internal::CompletionQueueTag { +class TagSaver final : public ::grpc::internal::CompletionQueueTag { public: explicit TagSaver(void* tag) : tag_(tag) {} ~TagSaver() override {} @@ -191,7 +194,7 @@ class TagSaver final : public internal::CompletionQueueTag { void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) { + ::grpc::CompletionQueue* cq, void* tag) { TagSaver* tag_saver = new TagSaver(tag); grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline, cq->cq(), tag_saver); @@ -199,7 +202,7 @@ void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) { - CompletionQueue cq; + ::grpc::CompletionQueue cq; bool ok = false; void* tag = nullptr; NotifyOnStateChangeImpl(last_observed, deadline, &cq, nullptr); @@ -214,7 +217,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { ShutdownCallback() { functor_run = &ShutdownCallback::Run; } // TakeCQ takes ownership of the cq into the shutdown callback // so that the shutdown callback will be responsible for destroying it - void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + void TakeCQ(::grpc::CompletionQueue* cq) { cq_ = cq; } // The Run function will get invoked by the completion queue library // when the shutdown is actually complete @@ -225,17 +228,17 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } private: - CompletionQueue* cq_ = nullptr; + ::grpc::CompletionQueue* cq_ = nullptr; }; } // namespace -CompletionQueue* Channel::CallbackCQ() { +::grpc::CompletionQueue* Channel::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-channel CQ registered grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + callback_cq_ = new ::grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -245,4 +248,4 @@ CompletionQueue* Channel::CallbackCQ() { return callback_cq_; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index b4fce79b99a..0ae1ecbf4ba 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -31,6 +31,11 @@ #include #include +namespace grpc_impl { + +class Channel; +} + namespace grpc { class DefaultGlobalClientCallbacks final @@ -83,8 +88,8 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); } -void ClientContext::set_call(grpc_call* call, - const std::shared_ptr& channel) { +void ClientContext::set_call( + grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) { grpc::internal::MutexLock lock(&mu_); GPR_ASSERT(call_ == nullptr); call_ = call; diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 3318ded7268..ca7038b8893 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -71,7 +71,7 @@ std::shared_ptr CreateCustomChannelWithInterceptors( interceptor_creators) { return creds ? creds->CreateChannelWithInterceptors( target, args, std::move(interceptor_creators)) - : ::grpc::CreateChannelInternal( + : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index 0ea311367e4..63e1d14eb34 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -26,8 +26,8 @@ namespace grpc { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 4a87076fb10..3b201afb5a7 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -30,8 +30,8 @@ namespace grpc { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 61260a27c66..ca26c3f0a9f 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -34,7 +34,7 @@ std::shared_ptr CreateInsecureChannelFromFd( const grpc::string& target, int fd) { grpc::internal::GrpcLibrary init_lib; init_lib.init(); - return grpc::CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), std::vector>()); @@ -46,7 +46,7 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return grpc::CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::vector>()); diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 7b22f23cf00..b74f4d0466b 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal( + channel_ = ::grpc::CreateChannelInternal( "", channel, std::vector>()); diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index b50131b385c..42564a31ec8 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -24,8 +24,12 @@ #include #include -namespace grpc { +namespace grpc_impl { + class Channel; +} + +namespace grpc { namespace testing { @@ -33,31 +37,31 @@ typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index eda8eb5764c..4e524077e37 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -927,6 +927,7 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a20e0706895..6e83956b8d8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -928,6 +928,7 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a73abacdd22..e78efd4fa8e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10316,6 +10316,7 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", @@ -10441,6 +10442,7 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", From 03b079499cba1390fb394f2d476988aa6347c41e Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 16 May 2019 22:18:31 -0700 Subject: [PATCH 057/676] Move CompletionQueue and Channel --- BUILD | 1 + BUILD.gn | 1 + CMakeLists.txt | 5 + Makefile | 5 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/create_channel_impl.h | 1 - include/grpcpp/generic/generic_stub_impl.h | 2 +- include/grpcpp/impl/codegen/async_stream.h | 2 - .../grpcpp/impl/codegen/async_unary_call.h | 1 - include/grpcpp/impl/codegen/call.h | 14 +- include/grpcpp/impl/codegen/call_op_set.h | 1 - .../grpcpp/impl/codegen/channel_interface.h | 16 +- include/grpcpp/impl/codegen/client_callback.h | 1 - .../grpcpp/impl/codegen/client_unary_call.h | 2 - .../grpcpp/impl/codegen/completion_queue.h | 20 +- .../impl/codegen/completion_queue_impl.h | 422 ++++++++++++++++++ .../grpcpp/impl/codegen/intercepted_channel.h | 13 +- include/grpcpp/impl/codegen/server_context.h | 5 +- .../grpcpp/impl/codegen/server_interface.h | 69 +-- include/grpcpp/impl/codegen/service_type.h | 3 +- include/grpcpp/server_builder.h | 7 - include/grpcpp/server_builder_impl.h | 7 +- src/compiler/cpp_generator.cc | 7 +- src/cpp/common/completion_queue_cc.cc | 12 +- test/cpp/codegen/compiler_test_golden | 8 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 29 files changed, 532 insertions(+), 99 deletions(-) create mode 100644 include/grpcpp/impl/codegen/completion_queue_impl.h diff --git a/BUILD b/BUILD index da5439648d4..e4d74f0f42e 100644 --- a/BUILD +++ b/BUILD @@ -2148,6 +2148,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", diff --git a/BUILD.gn b/BUILD.gn index 8ea6eeeced0..956ec372121 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1054,6 +1054,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/config_protobuf.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e79f073a5f..1d206536d8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3312,6 +3312,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -3928,6 +3929,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4362,6 +4364,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4560,6 +4563,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h @@ -4916,6 +4920,7 @@ foreach(_hdr include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h + include/grpcpp/impl/codegen/completion_queue_impl.h include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/core_codegen_interface.h diff --git a/Makefile b/Makefile index 4bcc6417816..763ed2be215 100644 --- a/Makefile +++ b/Makefile @@ -5669,6 +5669,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6293,6 +6294,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6699,6 +6701,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -6868,6 +6871,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ @@ -7230,6 +7234,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ + include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ diff --git a/build.yaml b/build.yaml index 0364be34caa..50b5d98bcf3 100644 --- a/build.yaml +++ b/build.yaml @@ -1253,6 +1253,7 @@ filegroups: - include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h + - include/grpcpp/impl/codegen/completion_queue_impl.h - include/grpcpp/impl/codegen/completion_queue_tag.h - include/grpcpp/impl/codegen/config.h - include/grpcpp/impl/codegen/core_codegen_interface.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a62b9c84a63..02de7798b5b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -163,6 +163,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', + 'include/grpcpp/impl/codegen/completion_queue_impl.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h', 'include/grpcpp/impl/codegen/config.h', 'include/grpcpp/impl/codegen/core_codegen_interface.h', diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index ebf8b96973e..02896e66444 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -28,7 +28,6 @@ #include namespace grpc_impl { - /// Create a new \a Channel pointing to \a target. /// /// \param target The URI of the endpoint to connect to. diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index 0a7338228c1..90414611cbd 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -29,12 +29,12 @@ namespace grpc { -class CompletionQueue; typedef ClientAsyncReaderWriter GenericClientAsyncReaderWriter; typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; } // namespace grpc namespace grpc_impl { +class CompletionQueue; /// Generic stubs provide a type-unsafe interface to call gRPC methods /// by name. diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index 6a23363bd6d..f95772650a2 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -28,8 +28,6 @@ namespace grpc { -class CompletionQueue; - namespace internal { /// Common interface for all client side asynchronous streaming. class ClientAsyncStreamingInterface { diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 89dcb124189..4b97cf29018 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -29,7 +29,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; /// An interface relevant for async client side unary RPCs (which send diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index c040c30dd9d..eefa4a7f9cd 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -21,9 +21,11 @@ #include #include -namespace grpc { +namespace grpc_impl { class CompletionQueue; +} +namespace grpc { namespace experimental { class ClientRpcInfo; class ServerRpcInfo; @@ -41,13 +43,13 @@ class Call final { call_(nullptr), max_receive_message_size_(-1) {} /** call is owned by the caller */ - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq) + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq) : call_hook_(call_hook), cq_(cq), call_(call), max_receive_message_size_(-1) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, experimental::ClientRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -55,7 +57,7 @@ class Call final { max_receive_message_size_(-1), client_rpc_info_(rpc_info) {} - Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq, + Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq, int max_receive_message_size, experimental::ServerRpcInfo* rpc_info) : call_hook_(call_hook), cq_(cq), @@ -68,7 +70,7 @@ class Call final { } grpc_call* call() const { return call_; } - CompletionQueue* cq() const { return cq_; } + ::grpc_impl::CompletionQueue* cq() const { return cq_; } int max_receive_message_size() const { return max_receive_message_size_; } @@ -82,7 +84,7 @@ class Call final { private: CallHook* call_hook_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; grpc_call* call_; int max_receive_message_size_; experimental::ClientRpcInfo* client_rpc_info_ = nullptr; diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 4ca87a99fca..d810625b3e4 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -48,7 +48,6 @@ namespace grpc { -class CompletionQueue; extern CoreCodegenInterface* g_core_codegen_interface; namespace internal { diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 57555285e18..9df233b5500 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -24,10 +24,13 @@ #include #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { class ChannelInterface; class ClientContext; -class CompletionQueue; template class ClientReader; @@ -74,7 +77,7 @@ class ChannelInterface { /// deadline expires. \a GetState needs to called to get the current state. template void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, - CompletionQueue* cq, void* tag) { + ::grpc_impl::CompletionQueue* cq, void* tag) { TimePoint deadline_tp(deadline); NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); } @@ -127,13 +130,14 @@ class ChannelInterface { friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq) = 0; + ::grpc_impl::CompletionQueue* cq) = 0; virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) = 0; virtual void* RegisterMethod(const char* method) = 0; virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) = 0; + ::grpc_impl::CompletionQueue* cq, + void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; @@ -146,7 +150,7 @@ class ChannelInterface { // change (even though this is private and non-API) virtual internal::Call CreateCallInternal(const internal::RpcMethod& method, ClientContext* context, - CompletionQueue* cq, + ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) { return internal::Call(); } @@ -159,7 +163,7 @@ class ChannelInterface { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index f0499858a05..dda9aec29f3 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -36,7 +36,6 @@ class Channel; namespace grpc { class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index b9f8e1663f1..e0f692b1783 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -27,9 +27,7 @@ namespace grpc { -class Channel; class ClientContext; -class CompletionQueue; namespace internal { class RpcMethod; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 472d95504dc..f67a3780979 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -16,28 +16,10 @@ * */ -/// A completion queue implements a concurrent producer-consumer queue, with -/// two main API-exposed methods: \a Next and \a AsyncNext. These -/// methods are the essential component of the gRPC C++ asynchronous API. -/// There is also a \a Shutdown method to indicate that a given completion queue -/// will no longer have regular events. This must be called before the -/// completion queue is destroyed. -/// All completion queue APIs are thread-safe and may be used concurrently with -/// any other completion queue API invocation; it is acceptable to have -/// multiple threads calling \a Next or \a AsyncNext on the same or different -/// completion queues, or to call these methods concurrently with a \a Shutdown -/// elsewhere. -/// \remark{All other API calls on completion queue should be completed before -/// a completion queue destructor is called.} #ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H #define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H -#include -#include -#include -#include -#include -#include +#include namespace grpc { diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h new file mode 100644 index 00000000000..5435f2fa165 --- /dev/null +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -0,0 +1,422 @@ +/* + * + * Copyright 2015-2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/// A completion queue implements a concurrent producer-consumer queue, with +/// two main API-exposed methods: \a Next and \a AsyncNext. These +/// methods are the essential component of the gRPC C++ asynchronous API. +/// There is also a \a Shutdown method to indicate that a given completion queue +/// will no longer have regular events. This must be called before the +/// completion queue is destroyed. +/// All completion queue APIs are thread-safe and may be used concurrently with +/// any other completion queue API invocation; it is acceptable to have +/// multiple threads calling \a Next or \a AsyncNext on the same or different +/// completion queues, or to call these methods concurrently with a \a Shutdown +/// elsewhere. +/// \remark{All other API calls on completion queue should be completed before +/// a completion queue destructor is called.} +#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H +#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H + +#include +#include +#include +#include +#include +#include + +struct grpc_completion_queue; + +namespace grpc_impl { + +class Channel; +class Server; +class ServerBuilder; +} // namespace grpc_impl +namespace grpc { + +template +class ClientReader; +template +class ClientWriter; +template +class ClientReaderWriter; +template +class ServerReader; +template +class ServerWriter; +namespace internal { +template +class ServerReaderWriterBody; +} // namespace internal + +class ChannelInterface; +class ClientContext; +class ServerContext; +class ServerInterface; + +namespace internal { +class CompletionQueueTag; +class RpcMethod; +template +class RpcMethodHandler; +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class BidiStreamingHandler; +template +class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; +template +class BlockingUnaryCallImpl; +template +class CallOpSet; +} // namespace internal + +extern CoreCodegenInterface* g_core_codegen_interface; + +} // namespace grpc + +namespace grpc_impl { + +/// A thin wrapper around \ref grpc_completion_queue (see \ref +/// src/core/lib/surface/completion_queue.h). +/// See \ref doc/cpp/perf_notes.md for notes on best practices for high +/// performance servers. +class CompletionQueue : private ::grpc::GrpcLibraryCodegen { + public: + /// Default constructor. Implicitly creates a \a grpc_completion_queue + /// instance. + CompletionQueue() + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, + nullptr}) {} + + /// Wrap \a take, taking ownership of the instance. + /// + /// \param take The completion queue instance to wrap. Ownership is taken. + explicit CompletionQueue(grpc_completion_queue* take); + + /// Destructor. Destroys the owned wrapped completion queue / instance. + ~CompletionQueue() { + ::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_); + } + + /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT. + enum NextStatus { + SHUTDOWN, ///< The completion queue has been shutdown and fully-drained + GOT_EVENT, ///< Got a new event; \a tag will be filled in with its + ///< associated value; \a ok indicating its success. + TIMEOUT ///< deadline was reached. + }; + + /// Read from the queue, blocking until an event is available or the queue is + /// shutting down. + /// + /// \param tag [out] Updated to point to the read event's tag. + /// \param ok [out] true if read a successful event, false otherwise. + /// + /// Note that each tag sent to the completion queue (through RPC operations + /// or alarms) will be delivered out of the completion queue by a call to + /// Next (or a related method), regardless of whether the operation succeeded + /// or not. Success here means that this operation completed in the normal + /// valid manner. + /// + /// Server-side RPC request: \a ok indicates that the RPC has indeed + /// been started. If it is false, the server has been Shutdown + /// before this particular call got matched to an incoming RPC. + /// + /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is + /// going to go to the wire. If it is false, it not going to the wire. This + /// would happen if the channel is either permanently broken or + /// transiently broken but with the fail-fast option. (Note that async unary + /// RPCs don't post a CQ tag at this point, nor do client-streaming + /// or bidi-streaming RPCs that have the initial metadata corked option set.) + /// + /// Client-side Write, Client-side WritesDone, Server-side Write, + /// Server-side Finish, Server-side SendInitialMetadata (which is + /// typically included in Write or Finish when not done explicitly): + /// \a ok means that the data/metadata/status/etc is going to go to the + /// wire. If it is false, it not going to the wire because the call + /// is already dead (i.e., canceled, deadline expired, other side + /// dropped the channel, etc). + /// + /// Client-side Read, Server-side Read, Client-side + /// RecvInitialMetadata (which is typically included in Read if not + /// done explicitly): \a ok indicates whether there is a valid message + /// that got read. If not, you know that there are certainly no more + /// messages that can ever be read from this stream. For the client-side + /// operations, this only happens because the call is dead. For the + /// server-sider operation, though, this could happen because the client + /// has done a WritesDone already. + /// + /// Client-side Finish: \a ok should always be true + /// + /// Server-side AsyncNotifyWhenDone: \a ok should always be true + /// + /// Alarm: \a ok is true if it expired, false if it was canceled + /// + /// \return true if got an event, false if the queue is fully drained and + /// shut down. + bool Next(void** tag, bool* ok) { + return (AsyncNextInternal(tag, ok, + ::grpc::g_core_codegen_interface->gpr_inf_future( + GPR_CLOCK_REALTIME)) != SHUTDOWN); + } + + /// Read from the queue, blocking up to \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// See documentation for CompletionQueue::Next for explanation of ok + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) { + ::grpc::TimePoint deadline_tp(deadline); + return AsyncNextInternal(tag, ok, deadline_tp.raw_time()); + } + + /// EXPERIMENTAL + /// First executes \a F, then reads from the queue, blocking up to + /// \a deadline (or the queue's shutdown). + /// Both \a tag and \a ok are updated upon success (if an event is available + /// within the \a deadline). A \a tag points to an arbitrary location usually + /// employed to uniquely identify an event. + /// + /// \param f [in] Function to execute before calling AsyncNext on this queue. + /// \param tag [out] Upon sucess, updated to point to the event's tag. + /// \param ok [out] Upon sucess, true if read a regular event, false + /// otherwise. + /// \param deadline [in] How long to block in wait for an event. + /// + /// \return The type of event read. + template + NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) { + CompletionQueueTLSCache cache = CompletionQueueTLSCache(this); + f(); + if (cache.Flush(tag, ok)) { + return GOT_EVENT; + } else { + return AsyncNext(tag, ok, deadline); + } + } + + /// Request the shutdown of the queue. + /// + /// \warning This method must be called at some point if this completion queue + /// is accessed with Next or AsyncNext. \a Next will not return false + /// until this method has been called and all pending tags have been drained. + /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .) + /// Only once either one of these methods does that (that is, once the queue + /// has been \em drained) can an instance of this class be destroyed. + /// Also note that applications must ensure that no work is enqueued on this + /// completion queue after this method is called. + void Shutdown(); + + /// Returns a \em raw pointer to the underlying \a grpc_completion_queue + /// instance. + /// + /// \warning Remember that the returned instance is owned. No transfer of + /// owership is performed. + grpc_completion_queue* cq() { return cq_; } + + protected: + /// Private constructor of CompletionQueue only visible to friend classes + CompletionQueue(const grpc_completion_queue_attributes& attributes) { + cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create( + ::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup( + &attributes), + &attributes, NULL); + InitialAvalanching(); // reserve this for the future shutdown + } + + private: + // Friend synchronous wrappers so that they can access Pluck(), which is + // a semi-private API geared towards the synchronous implementation. + template + friend class ::grpc::ClientReader; + template + friend class ::grpc::ClientWriter; + template + friend class ::grpc::ClientReaderWriter; + template + friend class ::grpc::ServerReader; + template + friend class ::grpc::ServerWriter; + template + friend class ::grpc::internal::ServerReaderWriterBody; + template + friend class ::grpc::internal::RpcMethodHandler; + template + friend class ::grpc::internal::ClientStreamingHandler; + template + friend class ::grpc::internal::ServerStreamingHandler; + template + friend class ::grpc::internal::TemplatedBidiStreamingHandler; + template <::grpc::StatusCode code> + friend class ::grpc::internal::ErrorMethodHandler; + friend class ::grpc_impl::Server; + friend class ::grpc::ServerContext; + friend class ::grpc::ServerInterface; + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + + // Friends that need access to constructor for callback CQ + friend class ::grpc_impl::Channel; + + // For access to Register/CompleteAvalanching + template + friend class ::grpc::internal::CallOpSet; + + /// EXPERIMENTAL + /// Creates a Thread Local cache to store the first event + /// On this completion queue queued from this thread. Once + /// initialized, it must be flushed on the same thread. + class CompletionQueueTLSCache { + public: + CompletionQueueTLSCache(CompletionQueue* cq); + ~CompletionQueueTLSCache(); + bool Flush(void** tag, bool* ok); + + private: + CompletionQueue* cq_; + bool flushed_; + }; + + NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); + + /// Wraps \a grpc_completion_queue_pluck. + /// \warning Must not be mixed with calls to \a Next. + bool Pluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = + ::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME); + while (true) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + bool ok = ev.success != 0; + void* ignored = tag; + if (tag->FinalizeResult(&ignored, &ok)) { + GPR_CODEGEN_ASSERT(ignored == tag); + return ok; + } + } + } + + /// Performs a single polling pluck on \a tag. + /// \warning Must not be mixed with calls to \a Next. + /// + /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already + /// shutdown. This is most likely a bug and if it is a bug, then change this + /// implementation to simple call the other TryPluck function with a zero + /// timeout. i.e: + /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME)) + void TryPluck(::grpc::internal::CompletionQueueTag* tag) { + auto deadline = + ::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME); + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT) return; + bool ok = ev.success != 0; + void* ignored = tag; + // the tag must be swallowed if using TryPluck + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if + /// the pluck() was successful and returned the tag. + /// + /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects + /// that the tag is internal not something that is returned to the user. + void TryPluck(::grpc::internal::CompletionQueueTag* tag, + gpr_timespec deadline) { + auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck( + cq_, tag, deadline, nullptr); + if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) { + return; + } + + bool ok = ev.success != 0; + void* ignored = tag; + GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); + } + + /// Manage state of avalanching operations : completion queue tags that + /// trigger other completion queue operations. The underlying core completion + /// queue should not really shutdown until all avalanching operations have + /// been finalized. Note that we maintain the requirement that an avalanche + /// registration must take place before CQ shutdown (which must be maintained + /// elsehwere) + void InitialAvalanching() { + gpr_atm_rel_store(&avalanches_in_flight_, static_cast(1)); + } + void RegisterAvalanching() { + gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(1)); + } + void CompleteAvalanching() { + if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(-1)) == 1) { + ::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_); + } + } + + grpc_completion_queue* cq_; // owned + + gpr_atm avalanches_in_flight_; +}; + +/// A specific type of completion queue used by the processing of notifications +/// by servers. Instantiated by \a ServerBuilder. +class ServerCompletionQueue : public CompletionQueue { + public: + bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; } + + protected: + /// Default constructor + ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {} + + private: + /// \param completion_type indicates whether this is a NEXT or CALLBACK + /// completion queue. + /// \param polling_type Informs the GRPC library about the type of polling + /// allowed on this completion queue. See grpc_cq_polling_type's description + /// in grpc_types.h for more details. + /// \param shutdown_cb is the shutdown callback used for CALLBACK api queues + ServerCompletionQueue(grpc_cq_completion_type completion_type, + grpc_cq_polling_type polling_type, + grpc_experimental_completion_queue_functor* shutdown_cb) + : CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, completion_type, polling_type, + shutdown_cb}), + polling_type_(polling_type) {} + + grpc_cq_polling_type polling_type_; + friend class ::grpc_impl::ServerBuilder; + friend class ::grpc_impl::Server; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index 5255a6d1472..cd0fcc06753 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -21,6 +21,10 @@ #include +namespace grpc_impl { +class CompletionQueue; +} + namespace grpc { namespace internal { @@ -46,7 +50,7 @@ class InterceptedChannel : public ChannelInterface { : channel_(channel), interceptor_pos_(pos) {} Call CreateCall(const RpcMethod& method, ClientContext* context, - CompletionQueue* cq) override { + ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } @@ -58,7 +62,8 @@ class InterceptedChannel : public ChannelInterface { } void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, + gpr_timespec deadline, + ::grpc_impl::CompletionQueue* cq, void* tag) override { return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag); } @@ -67,7 +72,9 @@ class InterceptedChannel : public ChannelInterface { return channel_->WaitForStateChangeImpl(last_observed, deadline); } - CompletionQueue* CallbackCQ() override { return channel_->CallbackCQ(); } + ::grpc_impl::CompletionQueue* CallbackCQ() override { + return channel_->CallbackCQ(); + } ChannelInterface* channel_; size_t interceptor_pos_; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index f65598db41f..c6903743938 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -43,12 +43,12 @@ struct census_context; namespace grpc_impl { +class CompletionQueue; class Server; } // namespace grpc_impl namespace grpc { class ClientContext; class GenericServerContext; -class CompletionQueue; class ServerInterface; template class ServerAsyncReader; @@ -90,6 +90,7 @@ class Call; class ServerReactor; } // namespace internal +class ServerInterface; namespace testing { class InteropServerContextInspector; class ServerContextTestSpouse; @@ -354,7 +355,7 @@ class ServerContext { gpr_timespec deadline_; grpc_call* call_; - CompletionQueue* cq_; + ::grpc_impl::CompletionQueue* cq_; bool sent_initial_metadata_; mutable std::shared_ptr auth_context_; mutable internal::MetadataMap client_metadata_; diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 26e997bfb56..d8d49344965 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -39,7 +39,6 @@ namespace grpc { class AsyncGenericService; class GenericServerContext; -class ServerCompletionQueue; class ServerContext; class Service; @@ -163,7 +162,8 @@ class ServerInterface : public internal::CallHook { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0; + virtual void Start(::grpc_impl::ServerCompletionQueue** cqs, + size_t num_cqs) = 0; virtual void ShutdownInternal(gpr_timespec deadline) = 0; @@ -178,9 +178,9 @@ class ServerInterface : public internal::CallHook { public: BaseAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); virtual ~BaseAsyncRequest(); bool FinalizeResult(void** tag, bool* status) override; @@ -192,8 +192,8 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; const bool delete_on_finalize_; grpc_call* call_; @@ -207,16 +207,17 @@ class ServerInterface : public internal::CallHook { public: RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - const char* name, internal::RpcMethod::RpcType type); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, const char* name, + internal::RpcMethod::RpcType type); virtual bool FinalizeResult(void** tag, bool* status) override { /* If we are done intercepting, then there is nothing more for us to do */ if (done_intercepting_) { return BaseAsyncRequest::FinalizeResult(tag, status); } - call_wrapper_ = internal::Call( + call_wrapper_ = ::grpc::internal::Call( call_, server_, call_cq_, server_->max_receive_message_size(), context_->set_server_rpc_info(name_, type_, *server_->interceptor_creators())); @@ -225,7 +226,7 @@ class ServerInterface : public internal::CallHook { protected: void IssueRequest(void* registered_method, grpc_byte_buffer** payload, - ServerCompletionQueue* notification_cq); + ::grpc_impl::ServerCompletionQueue* notification_cq); const char* name_; const internal::RpcMethod::RpcType type_; }; @@ -235,8 +236,9 @@ class ServerInterface : public internal::CallHook { NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()) { @@ -252,9 +254,9 @@ class ServerInterface : public internal::CallHook { PayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - Message* request) + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* request) : RegisteredAsyncRequest( server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()), @@ -309,9 +311,9 @@ class ServerInterface : public internal::CallHook { ServerInterface* const server_; ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; - CompletionQueue* const call_cq_; + ::grpc_impl::CompletionQueue* const call_cq_; - ServerCompletionQueue* const notification_cq_; + ::grpc_impl::ServerCompletionQueue* const notification_cq_; void* const tag_; Message* const request_; ByteBuffer payload_; @@ -321,9 +323,9 @@ class ServerInterface : public internal::CallHook { public: GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - bool delete_on_finalize); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, bool delete_on_finalize); bool FinalizeResult(void** tag, bool* status) override; @@ -335,9 +337,9 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, - Message* message) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag, Message* message) { GPR_CODEGEN_ASSERT(method); new PayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag, message); @@ -346,18 +348,19 @@ class ServerInterface : public internal::CallHook { void RequestAsyncCall(internal::RpcServiceMethod* method, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) { GPR_CODEGEN_ASSERT(method); new NoPayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag); } - void RequestAsyncGenericCall(GenericServerContext* context, - internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, - void* tag) { + void RequestAsyncGenericCall( + GenericServerContext* context, + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, tag, true); } @@ -382,7 +385,7 @@ class ServerInterface : public internal::CallHook { // Returns nullptr (rather than being pure) since this is a post-1.0 method // and adding a new pure method to an interface would be a breaking change // (even though this is private and non-API) - virtual CompletionQueue* CallbackCQ() { return nullptr; } + virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 762b049212f..f1d1272dc20 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -29,12 +29,11 @@ namespace grpc_impl { class Server; +class CompletionQueue; } // namespace grpc_impl namespace grpc { -class CompletionQueue; class ServerInterface; -class ServerCompletionQueue; class ServerContext; namespace internal { diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 89c4eba1d95..d9ec7c42f3d 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -21,13 +21,6 @@ #include -namespace grpc_impl { - -class Server; -class ServerCredentials; -class ResourceQuota; -} // namespace grpc_impl - namespace grpc { typedef ::grpc_impl::ServerBuilder ServerBuilder; diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 7c197a52f09..0de72cc397c 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -38,7 +38,10 @@ struct grpc_resource_quota; namespace grpc_impl { +class CompletionQueue; class ResourceQuota; +class Server; +class ServerCompletionQueue; class ServerCredentials; } // namespace grpc_impl @@ -153,7 +156,7 @@ class ServerBuilder { /// not polling the completion queue frequently) will have a significantly /// negative performance impact and hence should not be used in production /// use cases. - std::unique_ptr AddCompletionQueue( + std::unique_ptr AddCompletionQueue( bool is_frequently_polled = true); ////////////////////////////////////////////////////////////////////////////// @@ -359,7 +362,7 @@ class ServerBuilder { SyncServerSettings sync_server_settings_; /// List of completion queues added via \a AddCompletionQueue method. - std::vector cqs_; + std::vector cqs_; std::shared_ptr creds_; std::vector> plugins_; diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index ecec3206577..bcc849035c6 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -154,14 +154,15 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); printer->Print(vars, "\n"); + printer->Print(vars, "namespace grpc_impl {\n"); + printer->Print(vars, "class CompletionQueue;\n"); + printer->Print(vars, "class ServerCompletionQueue;\n"); + printer->Print(vars, "} // namespace grpc_impl\n\n"); printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "namespace experimental {\n"); printer->Print(vars, "template \n"); printer->Print(vars, "class MessageAllocator;\n"); printer->Print(vars, "} // namespace experimental\n"); - printer->Print(vars, "class CompletionQueue;\n"); - printer->Print(vars, "class Channel;\n"); - printer->Print(vars, "class ServerCompletionQueue;\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index 4bb3bcbd8b6..43c2eee96f8 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -24,9 +24,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; // 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here // i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create @@ -52,7 +52,8 @@ CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( case GRPC_QUEUE_SHUTDOWN: return SHUTDOWN; case GRPC_OP_COMPLETE: - auto core_cq_tag = static_cast(ev.tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(ev.tag); *ok = ev.success != 0; *tag = core_cq_tag; if (core_cq_tag->FinalizeResult(tag, ok)) { @@ -79,7 +80,8 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { flushed_ = true; if (grpc_completion_queue_thread_local_cache_flush(cq_->cq_, &res_tag, &res)) { - auto core_cq_tag = static_cast(res_tag); + auto core_cq_tag = + static_cast<::grpc::internal::CompletionQueueTag*>(res_tag); *ok = res == 1; if (core_cq_tag->FinalizeResult(tag, ok)) { return true; @@ -88,4 +90,4 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) { return false; } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 9e99bc7b0a2..2ad8e549899 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -40,14 +40,18 @@ #include #include +namespace grpc_impl { +class CompletionQueue; +class ServerCompletionQueue; +c +} // namespace grpc_impl + namespace grpc { namespace experimental { template class MessageAllocator; } // namespace experimental -class CompletionQueue; class Channel; -class ServerCompletionQueue; class ServerContext; } // namespace grpc diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 4e524077e37..667b9b3541e 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -959,6 +959,7 @@ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ +include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 6e83956b8d8..f4e6caa418a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -960,6 +960,7 @@ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ +include/grpcpp/impl/codegen/completion_queue_impl.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config_protobuf.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index e78efd4fa8e..34004d7d52d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10111,6 +10111,7 @@ "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", @@ -10188,6 +10189,7 @@ "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_impl.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/core_codegen_interface.h", From b4ef5388fcc50e3ec415c05035e6587e55e2d7a5 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 17 May 2019 09:35:40 -0700 Subject: [PATCH 058/676] Fix golden file --- test/cpp/codegen/compiler_test_golden | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 649ddca62fc..761c3ac6106 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -43,7 +43,6 @@ namespace grpc_impl { class CompletionQueue; class ServerCompletionQueue; -c } // namespace grpc_impl namespace grpc { @@ -51,9 +50,6 @@ namespace experimental { template class MessageAllocator; } // namespace experimental -class Channel; -class CompletionQueue; -class ServerCompletionQueue; class ServerContext; } // namespace grpc From fe85756a8afd6e257b378b73cea1681785efb58d Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 17 May 2019 10:15:41 -0700 Subject: [PATCH 059/676] Fix end2end tests --- test/cpp/end2end/client_callback_end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index ed7482b4be5..8cf6def1073 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -379,7 +379,7 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { ResetStub(); std::mutex mu; std::condition_variable cv; - bool done; + bool done = false; EchoRequest request; request.set_message("Hello locked world."); EchoResponse response; From 570bf332bc19f1a6e53df3604df85193db558bf4 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 17 May 2019 10:27:18 -0700 Subject: [PATCH 060/676] Memset in channel_filter ctor not needed and causes compiler warnings. Thanks to @KeithMoyer in #19044 and @soheilhy --- src/cpp/common/channel_filter.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 422e7bb65ee..8df6c7b98f5 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -30,7 +30,6 @@ namespace grpc { grpc_linked_mdelem* MetadataBatch::AddMetadata(const string& key, const string& value) { grpc_linked_mdelem* storage = new grpc_linked_mdelem; - memset(storage, 0, sizeof(grpc_linked_mdelem)); storage->md = grpc_mdelem_from_slices(SliceFromCopiedString(key), SliceFromCopiedString(value)); GRPC_LOG_IF_ERROR("MetadataBatch::AddMetadata", From 92aa0530fa5c1c4a0419413223cc6016529a661a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 17 May 2019 12:17:16 -0700 Subject: [PATCH 061/676] Changes to locking order --- test/core/surface/completion_queue_test.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 35a67387335..32f4debef13 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -388,9 +388,9 @@ static void test_callback(void) { static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); - gpr_mu_unlock(&shutdown_mu); // Signal when the shutdown callback is completed. gpr_cv_signal(&shutdown_cv); + gpr_mu_unlock(&shutdown_mu); } private: @@ -469,17 +469,18 @@ static void test_callback(void) { gpr_mu_unlock(&shutdown_mu); } - gpr_mu_lock(&mu); // Run the assertions to check if the test ran successfully. GPR_ASSERT(sumtags == counter); GPR_ASSERT(got_shutdown); - gpr_mu_unlock(&mu); + gpr_mu_lock(&shutdown_mu); got_shutdown = false; + gpr_mu_unlock(&shutdown_mu); } - gpr_mu_destroy(&mu); - gpr_mu_destroy(&shutdown_mu); + gpr_cv_destroy(&cv); gpr_cv_destroy(&shutdown_cv); + gpr_mu_destroy(&mu); + gpr_mu_destroy(&shutdown_mu); } struct thread_state { From a89b1763afa69d8a943a129971e36e2b0129751f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 17 May 2019 15:35:12 -0700 Subject: [PATCH 062/676] changes --- src/core/lib/surface/completion_queue.cc | 37 ++++++++++-------------- src/core/lib/surface/completion_queue.h | 3 +- src/core/lib/surface/server.cc | 2 +- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index f1b31e9cbba..b62f3fa6add 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -201,7 +201,7 @@ struct cq_vtable { bool (*begin_op)(grpc_completion_queue* cq, void* tag); void (*end_op)(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal); + void* done_arg, grpc_cq_completion* storage); grpc_event (*next)(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, @@ -358,17 +358,17 @@ static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); static void cq_end_op_for_next( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal = false); + grpc_cq_completion* storage); static void cq_end_op_for_pluck( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal = false); + grpc_cq_completion* storage); static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal = false); + grpc_cq_completion* storage); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -675,7 +675,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { static void cq_end_op_for_next( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { + grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -754,7 +754,7 @@ static void cq_end_op_for_next( static void cq_end_op_for_pluck( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { + grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -826,7 +826,7 @@ static void functor_callback(void* arg, grpc_error* error) { static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { + grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -857,25 +857,18 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); - if (internal) { - grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, - (error == GRPC_ERROR_NONE)); - } else { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); - } - + GRPC_CLOSURE_RUN( + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal) { - cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); + void* done_arg, grpc_cq_completion* storage) { + cq->vtable->end_op(cq, tag, error, done, done_arg, storage); } typedef struct { @@ -1353,7 +1346,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_RUN( GRPC_CLOSURE_CREATE( functor_callback, callback, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 3ba9fbb8765..d60fe6d6efe 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,8 +77,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal = false); + void* done_arg, grpc_cq_completion* storage); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 19f61c548d6..2377c4d8f23 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx, } grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event, - rc, &rc->completion, true); + rc, &rc->completion); } static void publish_new_rpc(void* arg, grpc_error* error) { From 6215ccb587810e87d76513cd03bcbe81e87c28d4 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 17 May 2019 16:22:43 -0700 Subject: [PATCH 063/676] resolve comments --- include/grpcpp/impl/codegen/message_allocator.h | 7 ++++++- test/cpp/end2end/message_allocator_end2end_test.cc | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/message_allocator.h b/include/grpcpp/impl/codegen/message_allocator.h index 422f8c2ea21..83544c64068 100644 --- a/include/grpcpp/impl/codegen/message_allocator.h +++ b/include/grpcpp/impl/codegen/message_allocator.h @@ -39,9 +39,14 @@ class RpcAllocatorState { template class MessageHolder : public RpcAllocatorState { public: - virtual void Release() { delete this; } + // Release this object. For example, if the custom allocator's + // AllocateMessasge creates an instance of a subclass with new, the Release() + // should do a "delete this;". + virtual void Release() = 0; RequestT* request() { return request_; } ResponseT* response() { return response_; } + + protected: void set_request(RequestT* request) { request_ = request; } void set_response(ResponseT* response) { response_ = response; } diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index 2abe26fe825..1c52259088a 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -346,6 +346,7 @@ class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { set_response( google::protobuf::Arena::CreateMessage(&arena_)); } + void Release() override { delete this; } void FreeRequest() override { GPR_ASSERT(0); } private: From 98461b0fa86caa0eb342c651e331662b3a373392 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 13 May 2019 10:56:57 -0700 Subject: [PATCH 064/676] xds enter fallback mode as long as no child policy is ready --- .../filters/client_channel/lb_policy/xds/xds.cc | 13 ++++++------- test/cpp/end2end/xds_end2end_test.cc | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 3eb94371c71..819bad6c00d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -493,9 +493,8 @@ class XdsLb : public LoadBalancingPolicy { // 1. The fallback timer fires, we enter fallback mode. // 2. Before the fallback timer fires, the LB channel becomes // TRANSIENT_FAILURE or the LB call fails, we enter fallback mode. - // 3. Before the fallback timer fires, we receive a response from the - // balancer, we cancel the fallback timer and use the response to update the - // locality map. + // 3. Before the fallback timer fires, if any child policy in the locality map + // becomes READY, we cancel the fallback timer. bool fallback_at_startup_checks_pending_ = false; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. @@ -1197,9 +1196,6 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xds_grpclb_destroy_serverlist( xdslb_policy->locality_serverlist_[0]->serverlist); } else { - // This is the first serverlist we've received, don't enter fallback - // mode. - xdslb_policy->MaybeCancelFallbackAtStartupChecks(); // Initialize locality serverlist, currently the list only handles // one child. xdslb_policy->locality_serverlist_.emplace_back( @@ -2046,7 +2042,10 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( return; } // At this point, child_ must be the current child policy. - if (state == GRPC_CHANNEL_READY) entry_->parent_->MaybeExitFallbackMode(); + if (state == GRPC_CHANNEL_READY) { + entry_->parent_->MaybeCancelFallbackAtStartupChecks(); + entry_->parent_->MaybeExitFallbackMode(); + } // If we are in fallback mode, ignore update request from the child policy. if (entry_->parent_->fallback_policy_ != nullptr) return; GPR_ASSERT(entry_->parent_->lb_chand_ != nullptr); diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index b876e062426..87a231c588d 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -1015,6 +1015,22 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { /* wait_for_ready */ false); } +TEST_F(SingleBalancerTest, FallbackIfResponseReceivedButChildNotReady) { + const int kFallbackTimeoutMs = 500 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Send a serverlist that only contains an unreachable backend before fallback + // timeout. + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + {grpc_pick_unused_port_or_die()}, {}), + 0); + // Because no child policy is ready before fallback timeout, we enter fallback + // mode. + WaitForBackend(0); +} + TEST_F(SingleBalancerTest, FallbackModeIsExitedWhenBalancerSaysToDropAllCalls) { // Return an unreachable balancer and one fallback backend. SetNextResolution({backends_[0]->port_}, kDefaultServiceConfig_.c_str()); From 440e9b79bfdaed986f89003fd8827910bcd87a77 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 May 2019 07:50:03 -0700 Subject: [PATCH 065/676] Fix bug in test health check service implementation. --- test/cpp/end2end/test_health_check_service_impl.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc index 0801e301996..5898527a6cd 100644 --- a/test/cpp/end2end/test_health_check_service_impl.cc +++ b/test/cpp/end2end/test_health_check_service_impl.cc @@ -54,6 +54,7 @@ Status HealthCheckServiceImpl::Watch( } if (response.status() != last_state) { writer->Write(response, ::grpc::WriteOptions()); + last_state = response.status(); } } gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), From 557a3e578db4cf307169547e21d7465dcadbbb76 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 17 May 2019 10:43:10 -0700 Subject: [PATCH 066/676] Remove 5s deadline on test server shutdown --- test/core/util/test_tcp_server.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 80d0634a9b9..a36cd80c83a 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -95,16 +95,13 @@ static void finish_pollset(void* arg, grpc_error* error) { void test_tcp_server_destroy(test_tcp_server* server) { grpc_core::ExecCtx exec_ctx; - gpr_timespec shutdown_deadline; grpc_closure do_nothing_cb; grpc_tcp_server_unref(server->tcp_server); GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr, grpc_schedule_on_exec_ctx); - shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(5, GPR_TIMESPAN)); - while (!server->shutdown && - gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { - test_tcp_server_poll(server, 1000); + grpc_core::ExecCtx::Get()->Flush(); + while (!server->shutdown) { + test_tcp_server_poll(server, 100); } grpc_pollset_shutdown(server->pollset, GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, From d22997e1ea5b5799cd1110f222025e207d1c554e Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 20 May 2019 10:22:30 -0700 Subject: [PATCH 067/676] Add back deadline --- test/core/util/test_tcp_server.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index a36cd80c83a..170584df2b9 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -95,13 +95,17 @@ static void finish_pollset(void* arg, grpc_error* error) { void test_tcp_server_destroy(test_tcp_server* server) { grpc_core::ExecCtx exec_ctx; + gpr_timespec shutdown_deadline; grpc_closure do_nothing_cb; grpc_tcp_server_unref(server->tcp_server); GRPC_CLOSURE_INIT(&do_nothing_cb, do_nothing, nullptr, grpc_schedule_on_exec_ctx); + shutdown_deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(5, GPR_TIMESPAN)); grpc_core::ExecCtx::Get()->Flush(); - while (!server->shutdown) { - test_tcp_server_poll(server, 100); + while (!server->shutdown && + gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { + test_tcp_server_poll(server, 1000); } grpc_pollset_shutdown(server->pollset, GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, From 56ff5a918f114372e7dfd9f130d4411b474bc466 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 20 May 2019 11:35:45 -0700 Subject: [PATCH 068/676] Address review comments - 1 --- test/core/surface/completion_queue_test.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 32f4debef13..ff6722ffb17 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -376,9 +376,7 @@ static void test_callback(void) { LOG_TEST("test_callback"); - gpr_mu_lock(&shutdown_mu); bool got_shutdown = false; - gpr_mu_unlock(&shutdown_mu); class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: ShutdownCallback(bool* done) : done_(done) { @@ -405,9 +403,7 @@ static void test_callback(void) { for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { int sumtags = 0; int counter = 0; - gpr_mu_lock(&mu); cb_counter = 0; - gpr_mu_unlock(&mu); { // reset exec_ctx types grpc_core::ExecCtx exec_ctx; @@ -472,9 +468,7 @@ static void test_callback(void) { // Run the assertions to check if the test ran successfully. GPR_ASSERT(sumtags == counter); GPR_ASSERT(got_shutdown); - gpr_mu_lock(&shutdown_mu); got_shutdown = false; - gpr_mu_unlock(&shutdown_mu); } gpr_cv_destroy(&cv); From f63dde8e8e7c0f7b0ec855f87085eba1f8ed23b5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 20 May 2019 11:45:07 -0700 Subject: [PATCH 069/676] Make validation function a global function --- .../grpcpp/support/channel_arguments_impl.h | 35 ++++++------------- src/cpp/common/channel_arguments.cc | 27 +++++++------- .../end2end/service_config_end2end_test.cc | 5 +-- 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 9a034078033..a137a5b7c7d 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -31,6 +31,15 @@ namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing + +namespace experimental { +/// Validates \a service_config_json. If valid, returns an empty string. +/// Otherwise, returns the validation error. +/// TODO(yashykt): Promote it to out of experimental once it is proved useful +/// and gRFC is accepted. +grpc::string ValidateServiceConfigJSON(const grpc::string& service_config_json); +} // namespace experimental + } // namespace grpc namespace grpc_impl { @@ -40,27 +49,8 @@ class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, /// concrete setters are provided. -/// This class derives from GrpcLibraryCodegen so that gRPC is initialized -/// before ValidateAndSetServiceConfigJSON is used. (Service config validation -/// methods are registered at initialization.) -class ChannelArguments : private ::grpc::GrpcLibraryCodegen { +class ChannelArguments { public: - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(ChannelArguments* args) : args_(args) {} - - /// Validates \a service_config_json. If valid, sets the service config and - /// returns an empty string. If invalid, returns the validation error. - grpc::string ValidateAndSetServiceConfigJSON( - const grpc::string& service_config_json); - - private: - ChannelArguments* args_; - }; - ChannelArguments(); ~ChannelArguments(); @@ -144,11 +134,6 @@ class ChannelArguments : private ::grpc::GrpcLibraryCodegen { return out; } - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - private: friend class grpc_impl::SecureChannelCredentials; friend class grpc::testing::ChannelArgumentsTest; diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 48dfe815042..2f32703814e 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -31,18 +31,13 @@ namespace grpc_impl { -namespace { -::grpc::internal::GrpcLibraryInitializer g_gli_initializer; -} // namespace - ChannelArguments::ChannelArguments() { - g_gli_initializer.summon(); // This will be ignored if used on the server side. SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + grpc::Version()); } ChannelArguments::ChannelArguments(const ChannelArguments& other) - : ::grpc::GrpcLibraryCodegen(), strings_(other.strings_) { + : strings_(other.strings_) { args_.reserve(other.args_.size()); auto list_it_dst = strings_.begin(); auto list_it_src = other.strings_.begin(); @@ -222,18 +217,22 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } -grpc::string -ChannelArguments::experimental_type::ValidateAndSetServiceConfigJSON( +} // namespace grpc_impl + +namespace grpc { +namespace experimental { +grpc::string ValidateServiceConfigJSON( const grpc::string& service_config_json) { + grpc_init(); grpc_error* error = GRPC_ERROR_NONE; grpc_core::ServiceConfig::Create(service_config_json.c_str(), &error); + grpc::string return_value; if (error != GRPC_ERROR_NONE) { - grpc::string return_value = grpc_error_string(error); + return_value = grpc_error_string(error); GRPC_ERROR_UNREF(error); - return return_value; } - args_->SetServiceConfigJSON(service_config_json); - return ""; + grpc_shutdown(); + return return_value; } - -} // namespace grpc_impl +} // namespace experimental +} // namespace grpc diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 74a304f6b26..e5c3a8e3eff 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -231,9 +231,10 @@ class ServiceConfigEnd2endTest : public ::testing::Test { std::shared_ptr BuildChannelWithDefaultServiceConfig() { ChannelArguments args; - EXPECT_THAT(args.experimental().ValidateAndSetServiceConfigJSON( + EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( ValidDefaultServiceConfig()), ::testing::StrEq("")); + args.SetServiceConfigJSON(ValidDefaultServiceConfig()); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); return ::grpc::CreateCustomChannel("fake:///", creds_, args); @@ -242,7 +243,7 @@ class ServiceConfigEnd2endTest : public ::testing::Test { std::shared_ptr BuildChannelWithInvalidDefaultServiceConfig() { ChannelArguments args; EXPECT_THAT( - args.experimental().ValidateAndSetServiceConfigJSON( + grpc::experimental::ValidateServiceConfigJSON( InvalidDefaultServiceConfig()), ::testing::HasSubstr("failed to parse JSON for service config")); args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); From 41ae267107706b4166ba057f027a0bc66d6e93ec Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 20 May 2019 11:46:18 -0700 Subject: [PATCH 070/676] Remove unnecessary header --- src/cpp/common/channel_arguments.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 2f32703814e..b97e1ed8da9 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" From f6601e1fc1c05f9eb47929fade49aecf1b80e569 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 20 May 2019 12:45:16 -0700 Subject: [PATCH 071/676] Add python deprecation notices. --- src/python/grpcio/README.rst | 8 ++++++++ src/python/grpcio_channelz/README.rst | 8 ++++++++ src/python/grpcio_health_checking/README.rst | 8 ++++++++ src/python/grpcio_reflection/README.rst | 8 ++++++++ src/python/grpcio_status/README.rst | 8 ++++++++ src/python/grpcio_testing/README.rst | 8 ++++++++ tools/distrib/python/grpcio_tools/README.rst | 8 ++++++++ 7 files changed, 56 insertions(+) diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst index f047243f82d..44d516ef6cb 100644 --- a/src/python/grpcio/README.rst +++ b/src/python/grpcio/README.rst @@ -3,6 +3,14 @@ gRPC Python Package for gRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Installation ------------ diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst index efeaa560646..d66d0c4f922 100644 --- a/src/python/grpcio_channelz/README.rst +++ b/src/python/grpcio_channelz/README.rst @@ -3,6 +3,14 @@ gRPC Python Channelz package Channelz is a live debug tool in gRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_health_checking/README.rst b/src/python/grpcio_health_checking/README.rst index 600734e50df..044377a5828 100644 --- a/src/python/grpcio_health_checking/README.rst +++ b/src/python/grpcio_health_checking/README.rst @@ -3,6 +3,14 @@ gRPC Python Health Checking Reference package for GRPC Python health checking. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_reflection/README.rst b/src/python/grpcio_reflection/README.rst index da99a449044..56f9953373b 100644 --- a/src/python/grpcio_reflection/README.rst +++ b/src/python/grpcio_reflection/README.rst @@ -3,6 +3,14 @@ gRPC Python Reflection package Reference package for reflection in GRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst index dc2f7b1dab1..16c59387a61 100644 --- a/src/python/grpcio_status/README.rst +++ b/src/python/grpcio_status/README.rst @@ -3,6 +3,14 @@ gRPC Python Status Proto Reference package for GRPC Python status proto mapping. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_testing/README.rst b/src/python/grpcio_testing/README.rst index c699b80fb67..968dec85071 100644 --- a/src/python/grpcio_testing/README.rst +++ b/src/python/grpcio_testing/README.rst @@ -3,6 +3,14 @@ gRPC Python Testing Package Testing utilities for gRPC Python +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index 32873b291fa..cc974eda315 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -3,6 +3,14 @@ gRPC Python Tools Package for gRPC Python tools. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Installation ------------ From cb9e2188ab05f983f447ed4cf8fb93b299bd224d Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 20 May 2019 12:45:16 -0700 Subject: [PATCH 072/676] Add python deprecation notices. --- src/python/grpcio/README.rst | 8 ++++++++ src/python/grpcio_channelz/README.rst | 8 ++++++++ src/python/grpcio_health_checking/README.rst | 8 ++++++++ src/python/grpcio_reflection/README.rst | 8 ++++++++ src/python/grpcio_status/README.rst | 8 ++++++++ src/python/grpcio_testing/README.rst | 8 ++++++++ tools/distrib/python/grpcio_tools/README.rst | 8 ++++++++ 7 files changed, 56 insertions(+) diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst index f047243f82d..44d516ef6cb 100644 --- a/src/python/grpcio/README.rst +++ b/src/python/grpcio/README.rst @@ -3,6 +3,14 @@ gRPC Python Package for gRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Installation ------------ diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst index efeaa560646..d66d0c4f922 100644 --- a/src/python/grpcio_channelz/README.rst +++ b/src/python/grpcio_channelz/README.rst @@ -3,6 +3,14 @@ gRPC Python Channelz package Channelz is a live debug tool in gRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_health_checking/README.rst b/src/python/grpcio_health_checking/README.rst index 600734e50df..044377a5828 100644 --- a/src/python/grpcio_health_checking/README.rst +++ b/src/python/grpcio_health_checking/README.rst @@ -3,6 +3,14 @@ gRPC Python Health Checking Reference package for GRPC Python health checking. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_reflection/README.rst b/src/python/grpcio_reflection/README.rst index da99a449044..56f9953373b 100644 --- a/src/python/grpcio_reflection/README.rst +++ b/src/python/grpcio_reflection/README.rst @@ -3,6 +3,14 @@ gRPC Python Reflection package Reference package for reflection in GRPC Python. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst index dc2f7b1dab1..16c59387a61 100644 --- a/src/python/grpcio_status/README.rst +++ b/src/python/grpcio_status/README.rst @@ -3,6 +3,14 @@ gRPC Python Status Proto Reference package for GRPC Python status proto mapping. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/src/python/grpcio_testing/README.rst b/src/python/grpcio_testing/README.rst index c699b80fb67..968dec85071 100644 --- a/src/python/grpcio_testing/README.rst +++ b/src/python/grpcio_testing/README.rst @@ -3,6 +3,14 @@ gRPC Python Testing Package Testing utilities for gRPC Python +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Dependencies ------------ diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index 32873b291fa..cc974eda315 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -3,6 +3,14 @@ gRPC Python Tools Package for gRPC Python tools. +Supported Python Versions +------------------------- +Python >= 3.5 + +Deprecated Python Versions +-------------------------- +Python == 2.7. Python 2.7 support will be removed on January 1, 2020. + Installation ------------ From 061dfc911f54c8a641ff7126dec77ac0c27430e7 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 20 May 2019 13:51:27 -0700 Subject: [PATCH 073/676] Bring back the internalization --- src/core/lib/surface/completion_queue.cc | 23 ++++++++++++++--------- src/core/lib/surface/completion_queue.h | 3 ++- src/core/lib/surface/server.cc | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index b62f3fa6add..64ceb45cf24 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -201,7 +201,7 @@ struct cq_vtable { bool (*begin_op)(grpc_completion_queue* cq, void* tag); void (*end_op)(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal); grpc_event (*next)(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, @@ -358,17 +358,17 @@ static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); static void cq_end_op_for_next( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage); + grpc_cq_completion* storage, bool internal); static void cq_end_op_for_pluck( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage); + grpc_cq_completion* storage, bool internal); static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage); + grpc_cq_completion* storage, bool internal); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -675,7 +675,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { static void cq_end_op_for_next( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage) { + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -754,7 +754,7 @@ static void cq_end_op_for_next( static void cq_end_op_for_pluck( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage) { + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -826,7 +826,7 @@ static void functor_callback(void* arg, grpc_error* error) { static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage) { + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -857,18 +857,23 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); + if (internal) { + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, + (error == GRPC_ERROR_NONE)); + } else { GRPC_CLOSURE_RUN( GRPC_CLOSURE_CREATE( functor_callback, functor, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_REF(error)); + } GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { - cq->vtable->end_op(cq, tag, error, done, done_arg, storage); + void* done_arg, grpc_cq_completion* storage, bool internal) { + cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); } typedef struct { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index d60fe6d6efe..3ba9fbb8765 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,7 +77,8 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, + bool internal = false); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 2377c4d8f23..19f61c548d6 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx, } grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event, - rc, &rc->completion); + rc, &rc->completion, true); } static void publish_new_rpc(void* arg, grpc_error* error) { From 5d95bf037d2ef325c0221d17a4c2ece586349f46 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 20 May 2019 14:09:10 -0700 Subject: [PATCH 074/676] Actually include README.rst in all packages --- src/python/grpcio_channelz/setup.py | 4 ++++ src/python/grpcio_health_checking/setup.py | 4 ++++ src/python/grpcio_reflection/setup.py | 4 ++++ src/python/grpcio_status/setup.py | 4 ++++ src/python/grpcio_testing/setup.py | 4 ++++ tools/distrib/python/grpcio_tools/setup.py | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py index f8c0e93913d..cc03809dda8 100644 --- a/src/python/grpcio_channelz/setup.py +++ b/src/python/grpcio_channelz/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -85,6 +88,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Channel Level Live Debug Information Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', classifiers=CLASSIFIERS, diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 5a09a80f6ae..dc2a69c1f43 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -17,6 +17,9 @@ import os import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -83,6 +86,7 @@ setuptools.setup( name='grpcio-health-checking', version=grpc_version.VERSION, description='Standard Health Checking Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py index f205069acd5..3fbcfda3229 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -85,6 +88,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Standard Protobuf Reflection Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', classifiers=CLASSIFIERS, diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 983d3ea430b..06d5dcfa8aa 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -17,6 +17,9 @@ import os import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -82,6 +85,7 @@ setuptools.setup( name='grpcio-status', version=grpc_version.VERSION, description='Status proto mapping for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index 18db71e0f09..05d2a130ed6 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -68,6 +71,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Testing utilities for gRPC Python', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 64c468cbf7b..e83e08b0431 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -31,6 +31,9 @@ from setuptools.command import build_ext # TODO(atash) add flag to disable Cython use +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + os.chdir(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.abspath('.')) @@ -191,6 +194,7 @@ setuptools.setup( name='grpcio-tools', version=grpc_version.VERSION, description='Protobuf code generator for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', From 2628983fb44f0718a61e3c87993b9729c47895fb Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 20 May 2019 14:09:10 -0700 Subject: [PATCH 075/676] Actually include README.rst in all packages --- src/python/grpcio_channelz/setup.py | 4 ++++ src/python/grpcio_health_checking/setup.py | 4 ++++ src/python/grpcio_reflection/setup.py | 4 ++++ src/python/grpcio_status/setup.py | 4 ++++ src/python/grpcio_testing/setup.py | 4 ++++ tools/distrib/python/grpcio_tools/setup.py | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py index f8c0e93913d..cc03809dda8 100644 --- a/src/python/grpcio_channelz/setup.py +++ b/src/python/grpcio_channelz/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -85,6 +88,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Channel Level Live Debug Information Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', classifiers=CLASSIFIERS, diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 5a09a80f6ae..dc2a69c1f43 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -17,6 +17,9 @@ import os import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -83,6 +86,7 @@ setuptools.setup( name='grpcio-health-checking', version=grpc_version.VERSION, description='Standard Health Checking Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py index f205069acd5..3fbcfda3229 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -85,6 +88,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Standard Protobuf Reflection Service for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', classifiers=CLASSIFIERS, diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 983d3ea430b..06d5dcfa8aa 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -17,6 +17,9 @@ import os import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -82,6 +85,7 @@ setuptools.setup( name='grpcio-status', version=grpc_version.VERSION, description='Status proto mapping for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index 18db71e0f09..05d2a130ed6 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -18,6 +18,9 @@ import sys import setuptools +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + # Ensure we're in the proper directory whether or not we're being used by pip. os.chdir(os.path.dirname(os.path.abspath(__file__))) @@ -68,6 +71,7 @@ setuptools.setup( version=grpc_version.VERSION, license='Apache License 2.0', description='Testing utilities for gRPC Python', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index 64c468cbf7b..e83e08b0431 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -31,6 +31,9 @@ from setuptools.command import build_ext # TODO(atash) add flag to disable Cython use +_PACKAGE_PATH = os.path.realpath(os.path.dirname(__file__)) +_README_PATH = os.path.join(_PACKAGE_PATH, 'README.rst') + os.chdir(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.abspath('.')) @@ -191,6 +194,7 @@ setuptools.setup( name='grpcio-tools', version=grpc_version.VERSION, description='Protobuf code generator for gRPC', + long_description=open(_README_PATH, 'r').read(), author='The gRPC Authors', author_email='grpc-io@googlegroups.com', url='https://grpc.io', From c681ff8e4b864622ffcaaa9476604a04de944636 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 20 May 2019 14:51:16 -0700 Subject: [PATCH 076/676] Rename root certificate bundle in gRPC-C++ pod --- gRPC-C++.podspec | 4 ++-- templates/gRPC-C++.podspec.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 57743df8c7c..55549b49af9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '1.22.0-dev' - version = '0.0.8-dev' + version = '0.0.9-dev' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' @@ -72,7 +72,7 @@ Pod::Spec.new do |s| s.default_subspecs = 'Interface', 'Implementation' # Certificates, to be able to establish TLS connections: - s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] } s.header_mappings_dir = 'include/grpcpp' diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index 43cb6db66c6..40368e422d9 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -140,7 +140,7 @@ s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '${modify_podspec_version_string('0.0.8', settings.version)}' + version = '${modify_podspec_version_string('0.0.9', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' @@ -188,7 +188,7 @@ s.default_subspecs = 'Interface', 'Implementation' # Certificates, to be able to establish TLS connections: - s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] } s.header_mappings_dir = 'include/grpcpp' From 90fbdc92f522af9f98297e08c0ed174361977d46 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Mon, 20 May 2019 08:05:01 -0700 Subject: [PATCH 077/676] Roll-forward "Config migration" This reverts commit 236ae12bb115c307d1cd7d0b88c7aaa082e3dd0a. --- BUILD | 16 +++++++ BUILD.gn | 2 + CMakeLists.txt | 2 + Makefile | 2 + build.yaml | 9 ++++ config.m4 | 2 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 ++ grpc.gemspec | 2 + grpc.gyp | 2 + package.xml | 2 + .../interop/app/src/main/cpp/grpc-interop.cc | 6 +-- .../filters/client_channel/backup_poller.cc | 11 +++-- .../client_channel/http_connect_handshaker.cc | 1 - .../resolver/dns/c_ares/dns_resolver_ares.cc | 14 +++--- .../resolver/dns/dns_resolver_selection.cc | 28 ++++++++++++ .../resolver/dns/dns_resolver_selection.h | 29 ++++++++++++ .../resolver/dns/native/dns_resolver.cc | 8 ++-- .../chttp2/transport/chttp2_plugin.cc | 7 ++- src/core/lib/debug/trace.cc | 20 ++++++--- src/core/lib/debug/trace.h | 8 ++++ src/core/lib/gpr/env.h | 6 --- src/core/lib/gpr/env_linux.cc | 2 +- src/core/lib/gpr/env_windows.cc | 5 --- src/core/lib/gpr/log.cc | 22 ++++------ src/core/lib/gprpp/fork.cc | 41 +++++------------ src/core/lib/iomgr/ev_posix.cc | 26 ++++++----- src/core/lib/iomgr/ev_posix.h | 3 ++ src/core/lib/iomgr/fork_posix.cc | 1 - src/core/lib/iomgr/iomgr.cc | 3 +- src/core/lib/profiling/basic_timers.cc | 14 ++++-- .../load_system_roots_linux.cc | 12 ++--- .../security_connector/security_connector.cc | 1 - .../security/security_connector/ssl_utils.cc | 44 +++++++++++-------- .../security/security_connector/ssl_utils.h | 6 ++- src/core/lib/surface/init.cc | 2 +- .../private/GRPCSecureChannelFactory.m | 3 +- .../CoreCronetEnd2EndTests.mm | 4 +- src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/bad_connection/close_fd_test.cc | 1 - test/core/bad_ssl/bad_ssl_test.cc | 4 +- .../resolvers/dns_resolver_test.cc | 8 ++-- test/core/end2end/fixtures/h2_full+trace.cc | 4 +- .../end2end/fixtures/h2_sockpair+trace.cc | 5 ++- test/core/end2end/fixtures/h2_spiffe.cc | 3 +- test/core/end2end/fixtures/h2_ssl.cc | 4 +- .../end2end/fixtures/h2_ssl_cred_reload.cc | 4 +- test/core/end2end/fixtures/h2_ssl_proxy.cc | 4 +- test/core/end2end/h2_ssl_cert_test.cc | 4 +- .../core/end2end/h2_ssl_session_reuse_test.cc | 4 +- test/core/end2end/tests/keepalive_timeout.cc | 14 +++--- test/core/gpr/log_test.cc | 13 ++++-- test/core/http/httpscli_test.cc | 3 +- test/core/iomgr/resolve_address_posix_test.cc | 18 ++++---- test/core/iomgr/resolve_address_test.cc | 13 +++--- test/core/security/credentials_test.cc | 2 +- test/core/security/security_connector_test.cc | 10 ++--- test/core/util/test_config.cc | 1 - test/cpp/end2end/async_end2end_test.cc | 12 +++-- test/cpp/end2end/end2end_test.cc | 12 +++-- test/cpp/naming/address_sorting_test.cc | 14 +++--- test/cpp/naming/cancel_ares_query_test.cc | 4 +- test/cpp/naming/resolver_component_test.cc | 1 - tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 24 +++++++++- tools/run_tests/run_microbenchmark.py | 2 +- .../run_tests/sanity/core_banned_functions.py | 4 -- 68 files changed, 358 insertions(+), 208 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h diff --git a/BUILD b/BUILD index 52c469f0b4a..d36aba2387c 100644 --- a/BUILD +++ b/BUILD @@ -1563,6 +1563,20 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_resolver_dns_selection", + srcs = [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + ], + hdrs = [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", + ], + language = "c++", + deps = [ + "grpc_base", + ], +) + grpc_cc_library( name = "grpc_resolver_dns_native", srcs = [ @@ -1572,6 +1586,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_resolver_dns_selection", ], ) @@ -1601,6 +1616,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_resolver_dns_selection", ], ) diff --git a/BUILD.gn b/BUILD.gn index ea5d544972f..62877a74539 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -324,6 +324,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc", "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f85bff572e6..2e4886b7b38 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1308,6 +1308,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/census/grpc_context.cc @@ -2703,6 +2704,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc diff --git a/Makefile b/Makefile index 9cf0ab03f09..f76b6878729 100644 --- a/Makefile +++ b/Makefile @@ -3788,6 +3788,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -5131,6 +5132,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/build.yaml b/build.yaml index fbfa0df86cd..3d7f44976b2 100644 --- a/build.yaml +++ b/build.yaml @@ -796,6 +796,7 @@ filegroups: uses: - grpc_base - grpc_client_channel + - grpc_resolver_dns_selection - name: grpc_resolver_dns_native src: - src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -803,6 +804,14 @@ filegroups: uses: - grpc_base - grpc_client_channel + - grpc_resolver_dns_selection +- name: grpc_resolver_dns_selection + headers: + - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h + src: + - src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc + uses: + - grpc_base - name: grpc_resolver_fake headers: - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h diff --git a/config.m4 b/config.m4 index 4dc6a7ce34e..bb30be56910 100644 --- a/config.m4 +++ b/config.m4 @@ -411,6 +411,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ + src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -694,6 +695,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake) diff --git a/config.w32 b/config.w32 index ec65248e0d6..c9faa8d9ac8 100644 --- a/config.w32 +++ b/config.w32 @@ -386,6 +386,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + "src\\core\\ext\\filters\\census\\grpc_context.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 57743df8c7c..df030f3a3dd 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -563,6 +563,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 682b7d80277..8ad00aad096 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -539,6 +539,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', @@ -868,6 +869,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1189,6 +1191,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index 36b325f8f0d..0bbf10fb361 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -473,6 +473,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) s.files += %w( src/core/ext/filters/http/client_authority_filter.h ) @@ -805,6 +806,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) s.files += %w( src/core/ext/filters/census/grpc_context.cc ) diff --git a/grpc.gyp b/grpc.gyp index 3a90eac28b5..eff5ab816b8 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -593,6 +593,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1352,6 +1353,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', diff --git a/package.xml b/package.xml index da12917dbee..eca74c8f167 100644 --- a/package.xml +++ b/package.xml @@ -478,6 +478,7 @@ + @@ -810,6 +811,7 @@ + diff --git a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc index 07834250d22..b5075529be2 100644 --- a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc +++ b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc @@ -18,8 +18,8 @@ #include #include -#include +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/cpp/interop/interop_client.h" extern "C" JNIEXPORT void JNICALL @@ -28,7 +28,7 @@ Java_io_grpc_interop_cpp_InteropActivity_configureSslRoots(JNIEnv* env, jstring path_raw) { const char* path = env->GetStringUTFChars(path_raw, (jboolean*)0); - gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", path); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, path); } std::shared_ptr GetClient(const char* host, @@ -45,7 +45,7 @@ std::shared_ptr GetClient(const char* host, credentials = grpc::InsecureChannelCredentials(); } - grpc::testing::ChannelCreationFunc channel_creation_func = + grpc::testing::ChannelCreationFunc channel_creation_func = std::bind(grpc::CreateChannel, host_port, credentials); return std::shared_ptr( new grpc::testing::InteropClient(channel_creation_func, true, false)); diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index a2d45c04026..dd761694414 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -56,9 +56,14 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; -GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, - DEFAULT_POLL_INTERVAL_MS, - "Client channel backup poll interval (ms)"); +GPR_GLOBAL_CONFIG_DEFINE_INT32( + grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS, + "Declares the interval in ms between two backup polls on client channels. " + "These polls are run in the timer thread so that gRPC can process " + "connection failures while there is no active polling thread. " + "They help reconnect disconnected client channels (mostly due to " + "idleness), so that the next RPC on this channel won't fail. Set to 0 to " + "turn off the backup polls."); static void init_globals() { gpr_mu_init(&g_poller_mu); diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc index 90a79843458..95366b57386 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker_registry.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/http/format_request.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 27d543363a3..00358736a94 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -32,12 +32,12 @@ #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -474,8 +474,9 @@ static bool should_use_ares(const char* resolver_env) { #endif /* GRPC_UV */ void grpc_resolver_dns_ares_init() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (should_use_ares(resolver_env)) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (should_use_ares(resolver.get())) { gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); @@ -491,16 +492,15 @@ void grpc_resolver_dns_ares_init() { grpc_core::UniquePtr( grpc_core::New())); } - gpr_free(resolver_env); } void grpc_resolver_dns_ares_shutdown() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (should_use_ares(resolver_env)) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (should_use_ares(resolver.get())) { address_sorting_shutdown(); grpc_ares_cleanup(); } - gpr_free(resolver_env); } #else /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc new file mode 100644 index 00000000000..07a617c14d5 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc @@ -0,0 +1,28 @@ +// +// Copyright 2019 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// This is similar to the sockaddr resolver, except that it supports a +// bunch of query args that are useful for dependency injection in tests. + +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_dns_resolver, "", + "Declares which DNS resolver to use. The default is ares if gRPC is built " + "with c-ares support. Otherwise, the value of this environment variable is " + "ignored.") diff --git a/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h new file mode 100644 index 00000000000..d0a3486ea38 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h @@ -0,0 +1,29 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H + +#include + +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_dns_resolver); + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_DNS_RESOLVER_SELECTION_H \ + */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 164d308c0dd..5ab75d02793 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -26,11 +26,11 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -274,8 +274,9 @@ class NativeDnsResolverFactory : public ResolverFactory { } // namespace grpc_core void grpc_resolver_dns_native_init() { - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "native") == 0) { gpr_log(GPR_DEBUG, "Using native dns resolver"); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( grpc_core::UniquePtr( @@ -291,7 +292,6 @@ void grpc_resolver_dns_native_init() { grpc_core::New())); } } - gpr_free(resolver_env); } void grpc_resolver_dns_native_shutdown() {} diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index 4c929d00ec9..ac13d73d3b5 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -23,8 +23,11 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" -GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, - "Disable flow control"); +GPR_GLOBAL_CONFIG_DEFINE_BOOL( + grpc_experimental_disable_flow_control, false, + "If set, flow control will be effectively disabled. Max out all values and " + "assume the remote peer does the same. Thus we can ignore any flow control " + "bookkeeping, error checking, and decision making"); void grpc_chttp2_plugin_init(void) { g_flow_control_enabled = diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc index cafdb15c699..84c0a3805d3 100644 --- a/src/core/lib/debug/trace.cc +++ b/src/core/lib/debug/trace.cc @@ -26,7 +26,11 @@ #include #include #include -#include "src/core/lib/gpr/env.h" + +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_trace, "", + "A comma separated list of tracers that provide additional insight into " + "how gRPC C core is processing requests via debug logs."); int grpc_tracer_set_enabled(const char* name, int enabled); @@ -133,12 +137,14 @@ static void parse(const char* s) { gpr_free(strings); } -void grpc_tracer_init(const char* env_var) { - char* e = gpr_getenv(env_var); - if (e != nullptr) { - parse(e); - gpr_free(e); - } +void grpc_tracer_init(const char* env_var_name) { + (void)env_var_name; // suppress unused variable error + grpc_tracer_init(); +} + +void grpc_tracer_init() { + grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_trace); + parse(value.get()); } void grpc_tracer_shutdown(void) {} diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 72e1a4eded7..6a4a8031ec4 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -24,7 +24,15 @@ #include #include +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_trace); + +// TODO(veblush): Remove this deprecated function once codes depending on this +// function are updated in the internal repo. void grpc_tracer_init(const char* env_var_name); + +void grpc_tracer_init(); void grpc_tracer_shutdown(void); #if defined(__has_feature) diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index fb9e0636d10..f5016c6fa06 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -34,12 +34,6 @@ char* gpr_getenv(const char* name); /* Sets the environment with the specified name to the specified value. */ void gpr_setenv(const char* name, const char* value); -/* This is a version of gpr_getenv that does not produce any output if it has to - use an insecure version of the function. It is ONLY to be used to solve the - problem in which we need to check an env variable to configure the verbosity - level of logging. So DO NOT USE THIS. */ -const char* gpr_getenv_silent(const char* name, char** dst); - /* Deletes the variable name from the environment. */ void gpr_unsetenv(const char* name); diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index e84a9f6064c..3a3aa541672 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -38,7 +38,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -const char* gpr_getenv_silent(const char* name, char** dst) { +static const char* gpr_getenv_silent(const char* name, char** dst) { const char* insecure_func_used = nullptr; char* result = nullptr; #if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index 72850a9587d..76c45fb87a7 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -30,11 +30,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/string_windows.h" -const char* gpr_getenv_silent(const char* name, char** dst) { - *dst = gpr_getenv(name); - return NULL; -} - char* gpr_getenv(const char* name) { char* result = NULL; DWORD size; diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc index 01ef112fb31..8a229b2adf1 100644 --- a/src/core/lib/gpr/log.cc +++ b/src/core/lib/gpr/log.cc @@ -22,12 +22,15 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include #include +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_verbosity, "ERROR", + "Default gRPC logging verbosity") + void gpr_default_log(gpr_log_func_args* args); static gpr_atm g_log_func = (gpr_atm)gpr_default_log; static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; @@ -72,29 +75,22 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { } void gpr_log_verbosity_init() { - char* verbosity = nullptr; - const char* insecure_getenv = gpr_getenv_silent("GRPC_VERBOSITY", &verbosity); + grpc_core::UniquePtr verbosity = GPR_GLOBAL_CONFIG_GET(grpc_verbosity); gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; - if (verbosity != nullptr) { - if (gpr_stricmp(verbosity, "DEBUG") == 0) { + if (strlen(verbosity.get()) > 0) { + if (gpr_stricmp(verbosity.get(), "DEBUG") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_DEBUG); - } else if (gpr_stricmp(verbosity, "INFO") == 0) { + } else if (gpr_stricmp(verbosity.get(), "INFO") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_INFO); - } else if (gpr_stricmp(verbosity, "ERROR") == 0) { + } else if (gpr_stricmp(verbosity.get(), "ERROR") == 0) { min_severity_to_print = static_cast(GPR_LOG_SEVERITY_ERROR); } - gpr_free(verbosity); } if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); } - - if (insecure_getenv != nullptr) { - gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", - insecure_getenv); - } } void gpr_set_log_function(gpr_log_func f) { diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index fdc7c5354bd..37552692373 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -26,8 +26,8 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/memory.h" /* @@ -35,6 +35,16 @@ * AROUND VERY SPECIFIC USE CASES. */ +#ifdef GRPC_ENABLE_FORK_SUPPORT +#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT true +#else +#define GRPC_ENABLE_FORK_SUPPORT_DEFAULT false +#endif // GRPC_ENABLE_FORK_SUPPORT + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_enable_fork_support, + GRPC_ENABLE_FORK_SUPPORT_DEFAULT, + "Enable folk support"); + namespace grpc_core { namespace internal { // The exec_ctx_count has 2 modes, blocked and unblocked. @@ -158,34 +168,7 @@ class ThreadState { void Fork::GlobalInit() { if (!override_enabled_) { -#ifdef GRPC_ENABLE_FORK_SUPPORT - support_enabled_ = true; -#endif - bool env_var_set = false; - char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); - if (env != nullptr) { - static const char* truthy[] = {"yes", "Yes", "YES", "true", - "True", "TRUE", "1"}; - static const char* falsey[] = {"no", "No", "NO", "false", - "False", "FALSE", "0"}; - for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == strcmp(env, truthy[i])) { - support_enabled_ = true; - env_var_set = true; - break; - } - } - if (!env_var_set) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) { - if (0 == strcmp(env, falsey[i])) { - support_enabled_ = false; - env_var_set = true; - break; - } - } - } - gpr_free(env); - } + support_enabled_ = GPR_GLOBAL_CONFIG_GET(grpc_enable_fork_support); } if (support_enabled_) { exec_ctx_state_ = grpc_core::New(); diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 47cf5b83b17..ddafb7b5539 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -31,13 +31,19 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" #include "src/core/lib/iomgr/internal_errqueue.h" +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_poll_strategy, "all", + "Declares which polling engines to try when starting gRPC. " + "This is a comma-separated list of engines, which are tried in priority " + "order first -> last.") + grpc_core::TraceFlag grpc_polling_trace(false, "polling"); /* Disabled by default */ @@ -46,16 +52,15 @@ grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace"); grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount"); grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); -#ifndef NDEBUG - // Polling API trace only enabled in debug builds +#ifndef NDEBUG #define GRPC_POLLING_API_TRACE(format, ...) \ if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_api_trace)) { \ gpr_log(GPR_INFO, "(polling-api) " format, __VA_ARGS__); \ } #else #define GRPC_POLLING_API_TRACE(...) -#endif +#endif // NDEBUG /** Default poll() function - a pointer so that it can be overridden by some * tests */ @@ -66,7 +71,7 @@ int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) { return poll(fds, nfds, timeout); } grpc_poll_function_type grpc_poll_function = aix_poll; -#endif +#endif // GPR_AIX grpc_wakeup_fd grpc_global_wakeup_fd; @@ -205,14 +210,11 @@ void grpc_register_event_engine_factory(const char* name, const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; } void grpc_event_engine_init(void) { - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s == nullptr) { - s = gpr_strdup("all"); - } + grpc_core::UniquePtr value = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); char** strings = nullptr; size_t nstrings = 0; - split(s, &strings, &nstrings); + split(value.get(), &strings, &nstrings); for (size_t i = 0; g_event_engine == nullptr && i < nstrings; i++) { try_engine(strings[i]); @@ -224,10 +226,10 @@ void grpc_event_engine_init(void) { gpr_free(strings); if (g_event_engine == nullptr) { - gpr_log(GPR_ERROR, "No event engine could be initialized from %s", s); + gpr_log(GPR_ERROR, "No event engine could be initialized from %s", + value.get()); abort(); } - gpr_free(s); } void grpc_event_engine_shutdown(void) { diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 0ca3a6f82fd..30bb5e40faf 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -24,11 +24,14 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy); + extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 7f8fb7e828b..629b08162fb 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -28,7 +28,6 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/fork.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/ev_posix.h" diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index fd011788a06..b86aa6f2d76 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -42,7 +42,8 @@ #include "src/core/lib/iomgr/timer_manager.h" GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, - "Abort when leak is found"); + "A debugging aid to cause a call to abort() when " + "gRPC objects are leaked past grpc_shutdown()"); static gpr_mu g_mu; static gpr_cv g_rcv; diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc index b19ad9fc23d..37689fe89d1 100644 --- a/src/core/lib/profiling/basic_timers.cc +++ b/src/core/lib/profiling/basic_timers.cc @@ -31,7 +31,8 @@ #include #include -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/profiling/timers.h" typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type; @@ -74,11 +75,16 @@ static __thread int g_thread_id; static int g_next_thread_id; static int g_writing_enabled = 1; +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_latency_trace, "latency_trace.txt", + "Output file name for latency trace") + static const char* output_filename() { if (output_filename_or_null == NULL) { - output_filename_or_null = gpr_getenv("LATENCY_TRACE"); - if (output_filename_or_null == NULL || - strlen(output_filename_or_null) == 0) { + grpc_core::UniquePtr value = + GPR_GLOBAL_CONFIG_GET(grpc_latency_trace); + if (strlen(value.get()) > 0) { + output_filename_or_null = value.release(); + } else { output_filename_or_null = "latency_trace.txt"; } } diff --git a/src/core/lib/security/security_connector/load_system_roots_linux.cc b/src/core/lib/security/security_connector/load_system_roots_linux.cc index 924fa8a3e26..82d5bf6bcdd 100644 --- a/src/core/lib/security/security_connector/load_system_roots_linux.cc +++ b/src/core/lib/security/security_connector/load_system_roots_linux.cc @@ -38,12 +38,15 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/iomgr/load_file.h" +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_system_ssl_roots_dir, "", + "Custom directory to SSL Roots"); + namespace grpc_core { namespace { @@ -139,10 +142,9 @@ grpc_slice CreateRootCertsBundle(const char* certs_directory) { grpc_slice LoadSystemRootCerts() { grpc_slice result = grpc_empty_slice(); // Prioritize user-specified custom directory if flag is set. - char* custom_dir = gpr_getenv("GRPC_SYSTEM_SSL_ROOTS_DIR"); - if (custom_dir != nullptr) { - result = CreateRootCertsBundle(custom_dir); - gpr_free(custom_dir); + UniquePtr custom_dir = GPR_GLOBAL_CONFIG_GET(grpc_system_ssl_roots_dir); + if (strlen(custom_dir.get()) > 0) { + result = CreateRootCertsBundle(custom_dir.get()); } // If the custom directory is empty/invalid/not specified, fallback to // distribution-specific directory. diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 96a19605466..47c0ad5aa3d 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,7 +28,6 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/load_file.h" diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index 1eefff6fe24..cb0d5437988 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,7 +27,6 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" @@ -46,7 +45,13 @@ static const char* installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif -/** Environment variable used as a flag to enable/disable loading system root +/** Config variable that points to the default SSL roots file. This file + must be a PEM encoded file with all the roots such as the one that can be + downloaded from https://pki.google.com/roots.pem. */ +GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_default_ssl_roots_file_path, "", + "Path to the default SSL roots file."); + +/** Config variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, "Disable loading system root certificates."); @@ -65,20 +70,22 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { /* -- Cipher suites. -- */ -/* Defines the cipher suites that we accept by default. All these cipher suites - are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-ECDSA-AES128-GCM-SHA256:" \ - "ECDHE-ECDSA-AES256-GCM-SHA384:" \ - "ECDHE-RSA-AES128-GCM-SHA256:" \ - "ECDHE-RSA-AES256-GCM-SHA384" - static gpr_once cipher_suites_once = GPR_ONCE_INIT; static const char* cipher_suites = nullptr; +// All cipher suites for default are compliant with HTTP2. +GPR_GLOBAL_CONFIG_DEFINE_STRING( + grpc_ssl_cipher_suites, + "ECDHE-ECDSA-AES128-GCM-SHA256:" + "ECDHE-ECDSA-AES256-GCM-SHA384:" + "ECDHE-RSA-AES128-GCM-SHA256:" + "ECDHE-RSA-AES256-GCM-SHA384", + "A colon separated list of cipher suites to use with OpenSSL") + static void init_cipher_suites(void) { - char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); - cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; + grpc_core::UniquePtr value = + GPR_GLOBAL_CONFIG_GET(grpc_ssl_cipher_suites); + cipher_suites = value.release(); } /* --- Util --- */ @@ -430,13 +437,12 @@ grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); const bool not_use_system_roots = GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); - // First try to load the roots from the environment. - char* default_root_certs_path = - gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); - if (default_root_certs_path != nullptr) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(default_root_certs_path, 1, &result)); - gpr_free(default_root_certs_path); + // First try to load the roots from the configuration. + UniquePtr default_root_certs_path = + GPR_GLOBAL_CONFIG_GET(grpc_default_ssl_roots_file_path); + if (strlen(default_root_certs_path.get()) > 0) { + GRPC_LOG_IF_ERROR( + "load_file", grpc_load_file(default_root_certs_path.get(), 1, &result)); } // Try overridden roots if needed. grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 080e277f944..1765a344c2a 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -26,6 +26,7 @@ #include #include +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/security_connector/security_connector.h" @@ -33,7 +34,10 @@ #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" -/* --- Util. --- */ +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_default_ssl_roots_file_path); +GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); + +/* --- Util --- */ /* --- URL schemes. --- */ #define GRPC_SSL_URL_SCHEME "https" diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 1ed1a66b184..2a6d307ddab 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -154,7 +154,7 @@ void grpc_init(void) { * at the appropriate time */ grpc_register_security_filters(); register_builtin_channel_init(); - grpc_tracer_init("GRPC_TRACE"); + grpc_tracer_init(); /* no more changes to channel init pipelines */ grpc_channel_init_finalize(); grpc_iomgr_start(); diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 7557367ed4a..e6522d7a27e 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -61,8 +61,7 @@ NSBundle *resourceBundle = [NSBundle bundleWithURL:[[bundle resourceURL] URLByAppendingPathComponent:resourceBundlePath]]; NSString *path = [resourceBundle pathForResource:rootsPEM ofType:@"pem"]; - setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, - [path cStringUsingEncoding:NSUTF8StringEncoding], 1); + setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", [path cStringUsingEncoding:NSUTF8StringEncoding], 1); }); NSData *rootsASCII = nil; diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index 2fac1be3d0e..0d081e4a410 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -37,11 +37,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -172,7 +172,7 @@ static char *roots_filename; GPR_ASSERT(roots_file != NULL); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 77753d7766c..2619ccf9740 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -385,6 +385,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', + 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index e8f297e77ea..78a1a5cc9a4 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -39,7 +39,6 @@ #include #include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 73d251eff4a..8dd55f64944 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,9 +25,9 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -133,7 +133,7 @@ int main(int argc, char** argv) { strcpy(root, "."); } if (argc == 2) { - gpr_setenv("GRPC_DEFAULT_SSL_ROOTS_FILE_PATH", argv[1]); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, argv[1]); } /* figure out our test name */ tmp = lunder - 1; diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index ed3b4e66472..129866b7d7f 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -21,8 +21,8 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "test/core/util/test_config.h" @@ -78,13 +78,13 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:10.2.1.1:1234"); test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); } - gpr_free(resolver_env); { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index ce8f6bf13a5..b8dbe261183 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -33,7 +33,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" @@ -105,7 +105,7 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); + GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index 4494d5c4746..7954bc1ddfc 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -35,7 +35,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/surface/channel.h" @@ -133,7 +133,8 @@ int main(int argc, char** argv) { /* force tracing on, with a value to force many code paths in trace.c to be taken */ - gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); + GPR_GLOBAL_CONFIG_SET(grpc_trace, "doesnt-exist,http,all"); + #ifdef GRPC_POSIX_SOCKET g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10 : 1; #else diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index 9ab796ea429..cdf091bac10 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -35,6 +35,7 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -277,7 +278,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); for (size_t ind = 0; ind < sizeof(configs) / sizeof(*configs); ind++) { grpc_end2end_tests(argc, argv, configs[ind]); diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 1fcd785e251..3fc9bc7f329 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,11 +25,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -167,7 +167,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 04d876ce3cd..1d54a431364 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,11 +25,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -190,7 +190,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index f1858079426..d5f695b1575 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,11 +25,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/fixtures/proxy.h" #include "test/core/util/port.h" @@ -208,7 +208,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index cb0800bf899..e9285778a2d 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,11 +25,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -366,7 +366,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index fbcdcc4b3f3..b2d0a5e1133 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,11 +25,11 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" @@ -265,7 +265,7 @@ int main(int argc, char** argv) { GPR_ASSERT(roots_file != nullptr); GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); fclose(roots_file); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, roots_filename); grpc_init(); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 3c33f0419ad..1750f6fe5ee 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -28,11 +28,15 @@ #include "src/core/ext/transport/chttp2/transport/frame_ping.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" #include "test/core/end2end/cq_verifier.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + static void* tag(intptr_t t) { return (void*)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -225,13 +229,13 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { * 200ms. In the success case, each ping ack should reset the keepalive timer so * that the keepalive ping is never sent. */ static void test_read_delays_keepalive(grpc_end2end_test_config config) { - char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); +#ifdef GRPC_POSIX_SOCKET + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); /* It is hard to get the timing right for the polling engine poll. */ - if (poller != nullptr && (0 == strcmp(poller, "poll"))) { - gpr_free(poller); + if ((0 == strcmp(poller.get(), "poll"))) { return; } - gpr_free(poller); +#endif // GRPC_POSIX_SOCKET const int kPingIntervalMS = 100; grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc index f96257738b2..e320daa33a7 100644 --- a/test/core/gpr/log_test.cc +++ b/test/core/gpr/log_test.cc @@ -21,9 +21,14 @@ #include #include -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" #include "test/core/util/test_config.h" +// Config declaration is supposed to be located at log.h but +// log.h doesn't include global_config headers because it has to +// be a strict C so declaration statement gets to be here. +GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_verbosity); + static bool log_func_reached = false; static void test_callback(gpr_log_func_args* args) { @@ -67,7 +72,7 @@ int main(int argc, char** argv) { /* gpr_log_verbosity_init() will be effective only once, and only before * gpr_set_log_verbosity() is called */ - gpr_setenv("GRPC_VERBOSITY", "ERROR"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "ERROR"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); @@ -75,7 +80,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); @@ -97,7 +102,7 @@ int main(int argc, char** argv) { test_log_function_unreached(GPR_DEBUG); /* gpr_log_verbosity_init() should not be effective */ - gpr_setenv("GRPC_VERBOSITY", "DEBUG"); + GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG"); gpr_log_verbosity_init(); test_log_function_reached(GPR_ERROR); test_log_function_unreached(GPR_INFO); diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index 326b0e95e25..e7250c206d8 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" #include "test/core/util/test_config.h" @@ -184,7 +185,7 @@ int main(int argc, char** argv) { /* Set the environment variable for the SSL certificate file */ char* pem_file; gpr_asprintf(&pem_file, "%s/src/core/tsi/test_creds/ca.pem", root); - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, pem_file); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, pem_file); gpr_free(pem_file); /* start the server */ diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc index 826c7e1fafa..112d7c2791b 100644 --- a/test/core/iomgr/resolve_address_posix_test.cc +++ b/test/core/iomgr/resolve_address_posix_test.cc @@ -29,6 +29,7 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" @@ -224,15 +225,16 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - cur_resolver); + resolver.get()); } if (gpr_stricmp(resolver_type, "native") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "native"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); abort(); @@ -246,12 +248,12 @@ int main(int argc, char** argv) { // c-ares resolver doesn't support UDS (ability for native DNS resolver // to handle this is only expected to be used by servers, which // unconditionally use the native DNS resolver). - char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (gpr_stricmp(resolver.get(), "native") == 0) { test_unix_socket(); test_unix_socket_path_name_too_long(); } - gpr_free(resolver_env); } gpr_cmdline_destroy(cl); diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 1f0c0e3e835..cbc03485d7f 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -27,7 +27,7 @@ #include -#include "src/core/lib/gpr/env.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -347,16 +347,17 @@ int main(int argc, char** argv) { // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); - const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", - cur_resolver); + resolver.get()); } if (gpr_stricmp(resolver_type, "native") == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "native"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "native"); } else if (gpr_stricmp(resolver_type, "ares") == 0) { #ifndef GRPC_UV - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); #endif } else { gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 11cfc8cc905..141346bca94 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -1161,7 +1161,7 @@ static void test_get_well_known_google_credentials_file_path(void) { GPR_ASSERT(path != nullptr); gpr_free(path); #if defined(GPR_POSIX_ENV) || defined(GPR_LINUX_ENV) - unsetenv("HOME"); + gpr_unsetenv("HOME"); path = grpc_get_well_known_google_credentials_file_path(); GPR_ASSERT(path == nullptr); gpr_setenv("HOME", home); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 496f064439c..c888c90c646 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -24,7 +24,6 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -394,7 +393,7 @@ static void test_default_ssl_roots(void) { /* First let's get the root through the override: set the env to an invalid value. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); grpc_set_ssl_roots_override_callback(override_roots_success); grpc_slice roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); @@ -405,7 +404,8 @@ static void test_default_ssl_roots(void) { /* Now let's set the env var: We should get the contents pointed value instead. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_env_var_file_path); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, + roots_env_var_file_path); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -414,7 +414,7 @@ static void test_default_ssl_roots(void) { /* Now reset the env var. We should fall back to the value overridden using the api. */ - gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, ""); + GPR_GLOBAL_CONFIG_SET(grpc_default_ssl_roots_file_path, ""); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); roots_contents = grpc_slice_to_c_string(roots); grpc_slice_unref(roots); @@ -423,7 +423,7 @@ static void test_default_ssl_roots(void) { /* Now setup a permanent failure for the overridden roots and we should get an empty slice. */ - gpr_setenv("GRPC_NOT_USE_SYSTEM_SSL_ROOTS", "true"); + GPR_GLOBAL_CONFIG_SET(grpc_not_use_system_ssl_roots, true); grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 476e424b1eb..5b248a01daa 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -28,7 +28,6 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/surface/init.h" diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 97275db6276..6ca0edf123e 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -33,7 +33,6 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" #include "src/proto/grpc/health/v1/health.grpc.pb.h" @@ -44,6 +43,10 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + #include using grpc::testing::EchoRequest; @@ -359,13 +362,14 @@ TEST_P(AsyncEnd2endTest, ReconnectChannel) { return; } int poller_slowdown_factor = 1; +#ifdef GRPC_POSIX_SOCKET // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll")) { + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + if (0 == strcmp(poller.get(), "poll")) { poller_slowdown_factor = 2; } - gpr_free(s); +#endif // GRPC_POSIX_SOCKET ResetStub(); SendRpc(1); server_->Shutdown(); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index bf3b374adc0..c027e5954ec 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,7 +35,6 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" @@ -47,6 +46,10 @@ #include "test/cpp/util/string_ref_helper.h" #include "test/cpp/util/test_credentials_provider.h" +#ifdef GRPC_POSIX_SOCKET +#include "src/core/lib/iomgr/ev_posix.h" +#endif // GRPC_POSIX_SOCKET + #include using grpc::testing::EchoRequest; @@ -809,11 +812,12 @@ TEST_P(End2endTest, ReconnectChannel) { int poller_slowdown_factor = 1; // It needs 2 pollset_works to reconnect the channel with polling engine // "poll" - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll")) { +#ifdef GRPC_POSIX_SOCKET + grpc_core::UniquePtr poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy); + if (0 == strcmp(poller.get(), "poll")) { poller_slowdown_factor = 2; } - gpr_free(s); +#endif // GRPC_POSIX_SOCKET ResetStub(); SendRpc(stub_.get(), 1, false); RestartServer(std::shared_ptr()); diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index bd685632c33..affc75bc634 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -36,10 +36,10 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" @@ -829,13 +829,13 @@ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) { } // namespace int main(int argc, char** argv) { - char* resolver = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver == nullptr || strlen(resolver) == 0) { - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); - } else if (strcmp("ares", resolver)) { - gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver); + grpc_core::UniquePtr resolver = + GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); + if (strlen(resolver.get()) == 0) { + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + } else if (strcmp("ares", resolver.get())) { + gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver.get()); } - gpr_free(resolver); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 674e72fdc52..667011ae291 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -29,10 +29,10 @@ #include #include "include/grpc/support/string_util.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" @@ -374,7 +374,7 @@ TEST( int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - gpr_setenv("GRPC_DNS_RESOLVER", "ares"); + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); // Sanity check the time that it takes to run the test // including the teardown time (the teardown // part of the test involves cancelling the DNS query, diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 93a92f68a6d..6cea8143907 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,7 +46,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 0365f284573..2c20d69e6e3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -951,6 +951,8 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallba src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ +src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a73abacdd22..8341971f51a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9271,7 +9271,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel" + "grpc_client_channel", + "grpc_resolver_dns_selection" ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", @@ -9301,7 +9302,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_client_channel" + "grpc_client_channel", + "grpc_resolver_dns_selection" ], "headers": [], "is_filegroup": true, @@ -9313,6 +9315,24 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [ + "gpr", + "grpc_base" + ], + "headers": [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + ], + "is_filegroup": true, + "language": "c", + "name": "grpc_resolver_dns_selection", + "src": [ + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc", + "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py index 4e4d05cdcd4..a7fde3007af 100755 --- a/tools/run_tests/run_microbenchmark.py +++ b/tools/run_tests/run_microbenchmark.py @@ -96,7 +96,7 @@ def collect_latency(bm_name, args): '--benchmark_filter=^%s$' % line, '--benchmark_min_time=0.05' ], - environ={'LATENCY_TRACE': '%s.trace' % fnize(line)}, + environ={'GRPC_LATENCY_TRACE': '%s.trace' % fnize(line)}, shortname='profile-%s' % fnize(line))) profile_analysis.append( jobset.JobSpec( diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 549ae14f5ab..ce9ff0dae21 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -45,10 +45,6 @@ BANNED_EXCEPT = { 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_run(': ['src/core/lib/iomgr/closure.cc'], 'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.cc'], - 'gpr_getenv_silent(': [ - 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/env_linux.cc', - 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc' - ], } errors = 0 From 0f21350b85c5887b570ab2553dbf3fcd19f57a63 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 20 May 2019 16:34:42 -0700 Subject: [PATCH 078/676] Gallantly fix typo --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 2 +- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 4a04b9f1939..48c3d002bbd 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2262,7 +2262,7 @@ void grpc_chttp2_mark_stream_closed(grpc_chttp2_transport* t, if (closed_read) { 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; + s->published_metadata[i] = GRPC_METADATA_PUBLISHED_AT_CLOSE; } } grpc_chttp2_maybe_complete_recv_initial_metadata(t, s); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0322dc72837..4ab46f9808b 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -499,7 +499,7 @@ typedef enum { GRPC_METADATA_NOT_PUBLISHED, GRPC_METADATA_SYNTHESIZED_FROM_FAKE, GRPC_METADATA_PUBLISHED_FROM_WIRE, - GPRC_METADATA_PUBLISHED_AT_CLOSE + GRPC_METADATA_PUBLISHED_AT_CLOSE } grpc_published_metadata_method; struct grpc_chttp2_stream { From de94662bc1e3bbb2cc37c84650faf313d1bde34b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Mon, 20 May 2019 17:34:11 -0700 Subject: [PATCH 079/676] version bump to v1.21.0 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 2cffca4ffc2..bf128416cf9 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.0-pre1" +version = "1.21.0" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 25f80af37e2..39f55d49dd2 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.0-pre1 + version: 1.21.0 filegroups: - name: alts_proto headers: From 535d0b150496f44544b3606f01636185ed19599c Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Mon, 20 May 2019 17:36:31 -0700 Subject: [PATCH 080/676] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7457016c3cd..dd3b5e3eb5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.0-pre1") +set(PACKAGE_VERSION "1.21.0") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 99238d17428..67495f250be 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.0-pre1 -CSHARP_VERSION = 1.21.0-pre1 +CPP_VERSION = 1.21.0 +CSHARP_VERSION = 1.21.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3f42684be03..a8bc964f582 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.0-pre1' - version = '0.0.8-pre1' + # version = '1.21.0' + version = '0.0.8' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.0-pre1' + grpc_version = '1.21.0' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6d369950b09..76f8cb3c8be 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.0-pre1' + version = '1.21.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index af515fb529b..4a48257b215 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.0-pre1' + version = '1.21.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index df8fcae0b41..8db3c7dc179 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.0-pre1' + version = '1.21.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 5458725ad76..83317db3b86 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.0-pre1' + version = '1.21.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 7ced9e795f8..96af492c9d9 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.0RC1 - 1.21.0RC1 + 1.21.0 + 1.21.0 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 8aeb99f2566..10801e5b713 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.0-pre1"; } +grpc::string Version() { return "1.21.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 402d251446a..494ce145dac 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.0-pre1"; + public const string CurrentVersion = "1.21.0"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 67647c7a96c..fe280590fd6 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.0-pre1 + 1.21.0 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index b8e247f8613..6cfe3a1ab8e 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.0-pre1 +set VERSION=1.21.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index d7db86900c7..77d6d4842eb 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.0-pre1' + v = '1.21.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index b011dd53275..4686dc2d1b7 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 28b45771ace..30f9ad18021 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.0" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 7d6f86c9bfe..33adae484ea 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.0RC1" +#define PHP_GRPC_VERSION "1.21.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 3a9cfc7a5e9..2b68fd5ff04 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.0rc1""" +__version__ = """1.21.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index d8434992dd5..cba5f3c0ebd 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index cbe46b76837..29a7523e926 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index cfa296588e8..80257d78a5d 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 54261c77f1d..bf61f4576a9 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 9a5e728adfb..850704d2f99 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 7cd0ffa30c1..2a6b1c4b65a 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 1a5e9f5385e..73cbe3913f6 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 30c4b3adae0..272a05310d6 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.0.pre1' + VERSION = '1.21.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 19c79e4f854..3f1c59e3592 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.0.pre1' + VERSION = '1.21.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index a91af1be0d2..5577597ef5d 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.0rc1' +VERSION = '1.21.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 0a399e0d1d7..ac397ab8202 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0-pre1 +PROJECT_NUMBER = 1.21.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e314e7e969e..e0ffeff6650 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0-pre1 +PROJECT_NUMBER = 1.21.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 12ffbb8a83182d3e76eb3f386ba9b99546779bcd Mon Sep 17 00:00:00 2001 From: kwasimensah Date: Tue, 21 May 2019 01:27:59 -0400 Subject: [PATCH 081/676] Add MessageLite type to grpc's config --- include/grpcpp/impl/codegen/config_protobuf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/grpcpp/impl/codegen/config_protobuf.h b/include/grpcpp/impl/codegen/config_protobuf.h index 8c2e9e67927..ce28f855529 100644 --- a/include/grpcpp/impl/codegen/config_protobuf.h +++ b/include/grpcpp/impl/codegen/config_protobuf.h @@ -30,9 +30,11 @@ #ifdef GRPC_USE_PROTO_LITE #include #define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite +#define GRPC_CUSTOM_MESSAGELITE ::google::protobuf::MessageLite #else #include #define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message +#define GRPC_CUSTOM_MESSAGELITE ::google::protobuf::MessageLite #endif #endif @@ -76,6 +78,7 @@ namespace grpc { namespace protobuf { typedef GRPC_CUSTOM_MESSAGE Message; +typedef GRPC_CUSTOM_MESSAGE MessageLite; typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; From 51a228002973be6b20a0ca9f133a5d581d3685bc Mon Sep 17 00:00:00 2001 From: kwasimensah Date: Tue, 21 May 2019 01:29:47 -0400 Subject: [PATCH 082/676] Add MessageLite overloads to proto serialization --- include/grpcpp/impl/codegen/proto_utils.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/proto_utils.h b/include/grpcpp/impl/codegen/proto_utils.h index d9db6de05c0..9d3fcee0c98 100644 --- a/include/grpcpp/impl/codegen/proto_utils.h +++ b/include/grpcpp/impl/codegen/proto_utils.h @@ -42,7 +42,7 @@ extern CoreCodegenInterface* g_core_codegen_interface; // ProtoBufferWriter must be a subclass of ::protobuf::io::ZeroCopyOutputStream. template -Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb, +Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, bool* own_buffer) { static_assert(std::is_base_of::value, @@ -68,7 +68,7 @@ Status GenericSerialize(const grpc::protobuf::Message& msg, ByteBuffer* bb, // BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream. template -Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) { +Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::MessageLite* msg) { static_assert(std::is_base_of::value, "ProtoBufferReader must be a subclass of " @@ -103,14 +103,14 @@ Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) { // be found in include/grpcpp/impl/codegen/serialization_traits.h. template class SerializationTraits::value>::type> { + grpc::protobuf::MessageLite, T>::value>::type> { public: - static Status Serialize(const grpc::protobuf::Message& msg, ByteBuffer* bb, + static Status Serialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, bool* own_buffer) { return GenericSerialize(msg, bb, own_buffer); } - static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::Message* msg) { + static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::MessageLite* msg) { return GenericDeserialize(buffer, msg); } }; From 3ec0967c1ef11c8b159b7cd7993846c050686b9d Mon Sep 17 00:00:00 2001 From: kwasimensah Date: Tue, 21 May 2019 01:52:36 -0400 Subject: [PATCH 083/676] Fix typo for using MessageLite --- include/grpcpp/impl/codegen/config_protobuf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/config_protobuf.h b/include/grpcpp/impl/codegen/config_protobuf.h index ce28f855529..3c9ab3442af 100644 --- a/include/grpcpp/impl/codegen/config_protobuf.h +++ b/include/grpcpp/impl/codegen/config_protobuf.h @@ -78,7 +78,7 @@ namespace grpc { namespace protobuf { typedef GRPC_CUSTOM_MESSAGE Message; -typedef GRPC_CUSTOM_MESSAGE MessageLite; +typedef GRPC_CUSTOM_MESSAGELITE MessageLite; typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; From cd0e02ae1c66c308debbea7476a0e40fedbaf5fd Mon Sep 17 00:00:00 2001 From: kwasimensah Date: Tue, 21 May 2019 02:29:00 -0400 Subject: [PATCH 085/676] Fixing formatting --- include/grpcpp/impl/codegen/proto_utils.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/proto_utils.h b/include/grpcpp/impl/codegen/proto_utils.h index 9d3fcee0c98..f9a7d3c0b34 100644 --- a/include/grpcpp/impl/codegen/proto_utils.h +++ b/include/grpcpp/impl/codegen/proto_utils.h @@ -68,7 +68,8 @@ Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, // BufferReader must be a subclass of ::protobuf::io::ZeroCopyInputStream. template -Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::MessageLite* msg) { +Status GenericDeserialize(ByteBuffer* buffer, + grpc::protobuf::MessageLite* msg) { static_assert(std::is_base_of::value, "ProtoBufferReader must be a subclass of " @@ -102,15 +103,17 @@ Status GenericDeserialize(ByteBuffer* buffer, grpc::protobuf::MessageLite* msg) // objects and grpc_byte_buffers. More information about SerializationTraits can // be found in include/grpcpp/impl/codegen/serialization_traits.h. template -class SerializationTraits::value>::type> { +class SerializationTraits< + T, typename std::enable_if< + std::is_base_of::value>::type> { public: - static Status Serialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb, - bool* own_buffer) { + static Status Serialize(const grpc::protobuf::MessageLite& msg, + ByteBuffer* bb, bool* own_buffer) { return GenericSerialize(msg, bb, own_buffer); } - static Status Deserialize(ByteBuffer* buffer, grpc::protobuf::MessageLite* msg) { + static Status Deserialize(ByteBuffer* buffer, + grpc::protobuf::MessageLite* msg) { return GenericDeserialize(buffer, msg); } }; From 118623d2933160891adfc0cb0c57cdf865758405 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 20 May 2019 14:51:16 -0700 Subject: [PATCH 086/676] Rename root certificate bundle in gRPC-C++ pod --- gRPC-C++.podspec | 4 ++-- templates/gRPC-C++.podspec.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a8bc964f582..91a72e75191 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '1.21.0' - version = '0.0.8' + version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' @@ -72,7 +72,7 @@ Pod::Spec.new do |s| s.default_subspecs = 'Interface', 'Implementation' # Certificates, to be able to establish TLS connections: - s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] } s.header_mappings_dir = 'include/grpcpp' diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index 43cb6db66c6..40368e422d9 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -140,7 +140,7 @@ s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '${modify_podspec_version_string('0.0.8', settings.version)}' + version = '${modify_podspec_version_string('0.0.9', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' @@ -188,7 +188,7 @@ s.default_subspecs = 'Interface', 'Implementation' # Certificates, to be able to establish TLS connections: - s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + s.resource_bundles = { 'gRPCCertificates-Cpp' => ['etc/roots.pem'] } s.header_mappings_dir = 'include/grpcpp' From 8ab582eb84ec9499bac58202f132a624f8e06dac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 May 2019 10:21:39 -0700 Subject: [PATCH 087/676] Bump up version to 1.21.1 --- CMakeLists.txt | 2 +- Makefile | 4 ++-- build.yaml | 2 +- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 31 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd3b5e3eb5b..0b0c75c0811 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.0") +set(PACKAGE_VERSION "1.21.1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 67495f250be..0d148ab3cd2 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.0 -CSHARP_VERSION = 1.21.0 +CPP_VERSION = 1.21.1 +CSHARP_VERSION = 1.21.1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 39f55d49dd2..0344ce18053 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.0 + version: 1.21.1 filegroups: - name: alts_proto headers: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 91a72e75191..ca27e4f34f3 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.0' + # version = '1.21.1' version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.0' + grpc_version = '1.21.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 76f8cb3c8be..ca3225b3694 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.0' + version = '1.21.1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 4a48257b215..2012515bbe9 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.0' + version = '1.21.1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 8db3c7dc179..c4a9f2889e9 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.0' + version = '1.21.1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 83317db3b86..31a1c448aa1 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.0' + version = '1.21.1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 96af492c9d9..6bcbd807566 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.21.0 - 1.21.0 + 1.21.1 + 1.21.1 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 10801e5b713..619220ce4e3 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.0"; } +grpc::string Version() { return "1.21.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 494ce145dac..5cf75df63ab 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.0.0"; + public const string CurrentAssemblyFileVersion = "1.21.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.0"; + public const string CurrentVersion = "1.21.1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index fe280590fd6..c4c40fe0c66 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.0 + 1.21.1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 6cfe3a1ab8e..65deb40679c 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.0 +set VERSION=1.21.1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 77d6d4842eb..8ac2dd7d303 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.0' + v = '1.21.1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 4686dc2d1b7..e410f8da012 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0" +#define GRPC_OBJC_VERSION_STRING @"1.21.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 30f9ad18021..95b112b156f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0" +#define GRPC_OBJC_VERSION_STRING @"1.21.1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index a9d0aebffca..3171442cc03 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.0", + "version": "1.21.1", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 33adae484ea..07a73698015 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.0" +#define PHP_GRPC_VERSION "1.21.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 2b68fd5ff04..4624e467fd8 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.0""" +__version__ = """1.21.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index cba5f3c0ebd..2451ef4a538 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 29a7523e926..591b5bd8fc5 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 80257d78a5d..c11487af7e8 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index bf61f4576a9..47628416c26 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 850704d2f99..713746a1598 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 2a6b1c4b65a..3fe457f304c 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 73cbe3913f6..103b532f38f 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 272a05310d6..1308aa4652e 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.0' + VERSION = '1.21.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 3f1c59e3592..38f7129d139 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.0' + VERSION = '1.21.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 5577597ef5d..872f821c2f6 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index ac397ab8202..c683fe91df1 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0 +PROJECT_NUMBER = 1.21.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e0ffeff6650..69f6a345afa 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0 +PROJECT_NUMBER = 1.21.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 035bf8eb14cc119dafec0aebd19e953e65142cb9 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 21 May 2019 10:50:18 -0700 Subject: [PATCH 088/676] Fix clang errors --- src/core/lib/surface/completion_queue.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 64ceb45cf24..5fa36392da5 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -861,18 +861,19 @@ static void cq_end_op_for_callback( grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); } else { - GRPC_CLOSURE_RUN( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); + GRPC_CLOSURE_RUN( + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); } GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal) { + void* done_arg, grpc_cq_completion* storage, + bool internal) { cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); } @@ -1351,11 +1352,10 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_RUN( - GRPC_CLOSURE_CREATE( - functor_callback, callback, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_RUN(GRPC_CLOSURE_CREATE(functor_callback, callback, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 5b3e0732ab926febe31ebe3f796da2c65b19e232 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 21 May 2019 10:59:17 -0700 Subject: [PATCH 089/676] Revert "Bump up version to 1.21.1" This reverts commit 8ab582eb84ec9499bac58202f132a624f8e06dac. --- CMakeLists.txt | 2 +- Makefile | 4 ++-- build.yaml | 2 +- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 31 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b0c75c0811..dd3b5e3eb5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.1") +set(PACKAGE_VERSION "1.21.0") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 0d148ab3cd2..67495f250be 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.1 -CSHARP_VERSION = 1.21.1 +CPP_VERSION = 1.21.0 +CSHARP_VERSION = 1.21.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 0344ce18053..39f55d49dd2 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.1 + version: 1.21.0 filegroups: - name: alts_proto headers: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ca27e4f34f3..91a72e75191 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.1' + # version = '1.21.0' version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.1' + grpc_version = '1.21.0' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ca3225b3694..76f8cb3c8be 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.1' + version = '1.21.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 2012515bbe9..4a48257b215 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.1' + version = '1.21.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index c4a9f2889e9..8db3c7dc179 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.1' + version = '1.21.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 31a1c448aa1..83317db3b86 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.1' + version = '1.21.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 6bcbd807566..96af492c9d9 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.21.1 - 1.21.1 + 1.21.0 + 1.21.0 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 619220ce4e3..10801e5b713 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.1"; } +grpc::string Version() { return "1.21.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 5cf75df63ab..494ce145dac 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.1.0"; + public const string CurrentAssemblyFileVersion = "1.21.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.1"; + public const string CurrentVersion = "1.21.0"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index c4c40fe0c66..fe280590fd6 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.1 + 1.21.0 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 65deb40679c..6cfe3a1ab8e 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.1 +set VERSION=1.21.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 8ac2dd7d303..77d6d4842eb 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.1' + v = '1.21.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index e410f8da012..4686dc2d1b7 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1" +#define GRPC_OBJC_VERSION_STRING @"1.21.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 95b112b156f..30f9ad18021 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1" +#define GRPC_OBJC_VERSION_STRING @"1.21.0" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 3171442cc03..a9d0aebffca 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.1", + "version": "1.21.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 07a73698015..33adae484ea 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.1" +#define PHP_GRPC_VERSION "1.21.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 4624e467fd8..2b68fd5ff04 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.1""" +__version__ = """1.21.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2451ef4a538..cba5f3c0ebd 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 591b5bd8fc5..29a7523e926 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c11487af7e8..80257d78a5d 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 47628416c26..bf61f4576a9 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 713746a1598..850704d2f99 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 3fe457f304c..2a6b1c4b65a 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 103b532f38f..73cbe3913f6 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 1308aa4652e..272a05310d6 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.1' + VERSION = '1.21.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 38f7129d139..3f1c59e3592 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.1' + VERSION = '1.21.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 872f821c2f6..5577597ef5d 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index c683fe91df1..ac397ab8202 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1 +PROJECT_NUMBER = 1.21.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 69f6a345afa..e0ffeff6650 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1 +PROJECT_NUMBER = 1.21.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From ccc105f3fdc0e017b8510f694f2ebb9c67c90324 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 21 May 2019 11:07:43 -0700 Subject: [PATCH 090/676] Move GRPC_CLOSURE_RUN to GRPC_CLOSURE_SCHED - As here we want it to be scheduled for execution later. --- src/core/lib/surface/completion_queue.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 5fa36392da5..d0ed1a9f673 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -861,7 +861,7 @@ static void cq_end_op_for_callback( grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); } else { - GRPC_CLOSURE_RUN( + GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, functor, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), @@ -1352,10 +1352,11 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_RUN(GRPC_CLOSURE_CREATE(functor_callback, callback, - grpc_core::Executor::Scheduler( - grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, callback, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From f131adf89c0fb510b755a390a4b833c887c0706c Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 21 May 2019 15:52:40 -0700 Subject: [PATCH 091/676] Fix bazel incompatible changes When building grpc with the upcoming `--incompatible_depset_is_not_iterable` flag, these violations were found --- bazel/generate_cc.bzl | 6 +++--- bazel/python_rules.bzl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 29a888f608f..b7edcda702f 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -41,11 +41,11 @@ def _join_directories(directories): def generate_cc_impl(ctx): """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources] + protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources.to_list()] includes = [ f for src in ctx.attr.srcs - for f in src.proto.transitive_imports + for f in src.proto.transitive_imports.to_list() ] outs = [] proto_root = get_proto_root( @@ -128,7 +128,7 @@ def generate_cc_impl(ctx): arguments += ["-I{0}".format(f + "/../..")] well_known_proto_files = [ f - for f in ctx.attr.well_known_protos.files + for f in ctx.attr.well_known_protos.files.to_list() ] ctx.actions.run( diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl index 2f3b38af002..17004f3474d 100644 --- a/bazel/python_rules.bzl +++ b/bazel/python_rules.bzl @@ -33,7 +33,7 @@ def _generate_py_impl(context): includes = [ file for src in context.attr.deps - for file in src.proto.transitive_imports + for file in src.proto.transitive_imports.to_list() ] proto_root = get_proto_root(context.label.workspace_root) format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) From b30b8e378f16430754bfaafb90f1206d52a08efc Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 21 May 2019 18:33:05 -0700 Subject: [PATCH 092/676] Verify the validity of python artifacts --- tools/run_tests/artifacts/build_artifact_python.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index e451ced338f..831566d51e4 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -130,5 +130,8 @@ then cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi +"${PIP}" install twine + +twine check dist/* tools/distrib/python/grpcio_tools/dist/* cp -r dist/* "$ARTIFACT_DIR" cp -r tools/distrib/python/grpcio_tools/dist/* "$ARTIFACT_DIR" From 189697eb30c3da55f80e66a23eb9a118e1c833d2 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 21 May 2019 19:47:12 -0700 Subject: [PATCH 093/676] Compensate for https://github.com/pypa/wheel/issues/189 --- src/python/grpcio/README.rst | 8 ++++---- tools/distrib/python/grpcio_tools/README.rst | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst index 44d516ef6cb..07c94342de1 100644 --- a/src/python/grpcio/README.rst +++ b/src/python/grpcio/README.rst @@ -16,8 +16,8 @@ Installation gRPC Python is available for Linux, macOS, and Windows. -From PyPI -~~~~~~~~~ +Installing From PyPI +~~~~~~~~~~~~~~~~~~~~ If you are installing locally... @@ -45,8 +45,8 @@ n.b. On Windows and on Mac OS X one *must* have a recent release of :code:`pip` to retrieve the proper wheel from PyPI. Be sure to upgrade to the latest version! -From Source -~~~~~~~~~~~ +Installing From Source +~~~~~~~~~~~~~~~~~~~~~~ Building from source requires that you have the Python headers (usually a package named :code:`python-dev`). diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index cc974eda315..2fe79350a84 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -17,8 +17,8 @@ Installation The gRPC Python tools package is available for Linux, Mac OS X, and Windows running Python 2.7. -From PyPI -~~~~~~~~~ +Installing From PyPI +~~~~~~~~~~~~~~~~~~~~ If you are installing locally... @@ -50,8 +50,8 @@ You might also need to install Cython to handle installation via the source distribution if gRPC Python's system coverage with wheels does not happen to include your system. -From Source -~~~~~~~~~~~ +Installing From Source +~~~~~~~~~~~~~~~~~~~~~~ Building from source requires that you have the Python headers (usually a package named :code:`python-dev`) and Cython installed. It further requires a From 705a34884c748cda85facd4b52e5c4f513f41555 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 22 May 2019 09:42:56 -0700 Subject: [PATCH 094/676] Properly invoke twine --- tools/run_tests/artifacts/build_artifact_python.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 831566d51e4..e35a3b67bb4 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -130,8 +130,9 @@ then cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi +# Ensure the generated artifacts are valid. "${PIP}" install twine +"${PYTHON}" -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* -twine check dist/* tools/distrib/python/grpcio_tools/dist/* cp -r dist/* "$ARTIFACT_DIR" cp -r tools/distrib/python/grpcio_tools/dist/* "$ARTIFACT_DIR" From 18a9e00b333d8aa6d2a270ce229ae32657033baa Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Wed, 22 May 2019 09:53:18 -0700 Subject: [PATCH 095/676] Document the Watch() method that got added to health/v1/health.proto --- doc/health-checking.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/health-checking.md b/doc/health-checking.md index 7be8107b60f..22b6e1b4c09 100644 --- a/doc/health-checking.md +++ b/doc/health-checking.md @@ -43,6 +43,8 @@ message HealthCheckResponse { service Health { rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } ``` @@ -68,3 +70,8 @@ matching semantics that both the client and server agree upon. A client can declare the server as unhealthy if the rpc is not finished after some amount of time. The client should be able to handle the case where server does not have the Health service. + +A client can call the `Watch` method to perform a streaming health-check. +The server will immediately send back a message indicating the current +serving status. It will then subsequently send a new message whenever +the service's serving status changes. From 64d26e617f7866cb7aa322b71dc56e7498367d88 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 22 May 2019 10:30:22 -0700 Subject: [PATCH 096/676] Bump version to v1.21.1-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index bf128416cf9..39777d9f723 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.0" +version = "1.21.1-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 39f55d49dd2..b6508734295 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.0 + version: 1.21.1-pre1 filegroups: - name: alts_proto headers: From 5207867e2d69737a7aa4fb6c158298cdb69c6a70 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 22 May 2019 10:37:00 -0700 Subject: [PATCH 097/676] Ensure windows artifacts are valid as well. --- tools/run_tests/artifacts/build_artifact_python.bat | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/artifacts/build_artifact_python.bat b/tools/run_tests/artifacts/build_artifact_python.bat index 795e80dc40d..e160a101228 100644 --- a/tools/run_tests/artifacts/build_artifact_python.bat +++ b/tools/run_tests/artifacts/build_artifact_python.bat @@ -46,6 +46,10 @@ pushd tools\distrib\python\grpcio_tools python setup.py bdist_wheel || goto :error popd +@rem Ensure the generate artifacts are valid. +pip install twine +python -m twine check dist\* tools\distrib\python\grpcio_tools\dist\* || goto :error + xcopy /Y /I /S dist\* %ARTIFACT_DIR% || goto :error xcopy /Y /I /S tools\distrib\python\grpcio_tools\dist\* %ARTIFACT_DIR% || goto :error From 2e31120724ace26a939bb2c34892e1eb2b9cc8d0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 22 May 2019 10:42:39 -0700 Subject: [PATCH 098/676] Fix StressTests on Mac --- src/objective-c/tests/Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 146abf5b0e0..c9d620ca2e9 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -112,7 +112,7 @@ post_install do |installer| # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void # function" warning config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' - config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1 GRPC_CFSTREAM=1' end end From 4f7f561564e52b0f2dd97ac661594d2449886df4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 22 May 2019 10:42:50 -0700 Subject: [PATCH 099/676] Add synchronization to bm test - since we made the callback run on another thread, add synchronization in bm tests as well --- test/cpp/microbenchmarks/bm_cq.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 50eb9454fbe..1f0b9621b21 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -166,6 +166,9 @@ class TagCallback : public grpc_experimental_completion_queue_functor { int* iter_; }; +static gpr_mu shutdown_mu; +static gpr_cv shutdown_cv; + // Check if completion queue is shut down class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: @@ -174,7 +177,10 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); + gpr_cv_signal(&shutdown_cv); + gpr_mu_unlock(&shutdown_mu); } private: @@ -185,6 +191,8 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { TrackCounters track_counters; int iteration = 0; TagCallback tag_cb(&iteration); + gpr_mu_init(&shutdown_mu); + gpr_cv_init(&shutdown_cv); bool got_shutdown = false; ShutdownCallback shutdown_cb(&got_shutdown); grpc_completion_queue* cc = @@ -198,9 +206,19 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { nullptr, &completion); } shutdown_and_destroy(cc); + + gpr_mu_lock(&shutdown_mu); + while (!got_shutdown) { + // Wait for the shutdown callback to complete. + gpr_cv_wait(&shutdown_cv, &shutdown_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&shutdown_mu); GPR_ASSERT(got_shutdown); GPR_ASSERT(iteration == static_cast(state.iterations())); track_counters.Finish(state); + gpr_cv_destroy(&shutdown_cv); + gpr_mu_destroy(&shutdown_mu); } BENCHMARK(BM_Callback_CQ_Pass1Core); From 4a208f0071b0ece3a36bf3be4fc3c7602cce2cd8 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Wed, 22 May 2019 10:48:54 -0700 Subject: [PATCH 100/676] Add v1.21.0 releases of grpc-go to interop matrix --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 234c71295b3..f9c069f6389 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -124,6 +124,7 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo(runtime_subset=['go1.11'])), ('v1.19.0', ReleaseInfo(runtime_subset=['go1.11'])), ('v1.20.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.21.0', ReleaseInfo(runtime_subset=['go1.11'])), ]), 'java': OrderedDict([ From 60f23bd38c6dd95a14fcb123d0c9a9cf6729a25e Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Wed, 22 May 2019 10:53:58 -0700 Subject: [PATCH 101/676] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd3b5e3eb5b..d335591779c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.0") +set(PACKAGE_VERSION "1.21.1-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 67495f250be..36f3f051dd3 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.0 -CSHARP_VERSION = 1.21.0 +CPP_VERSION = 1.21.1-pre1 +CSHARP_VERSION = 1.21.1-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 91a72e75191..4286e3d57e7 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.0' - version = '0.0.9' + # version = '1.21.1-pre1' + version = '0.0.9-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.0' + grpc_version = '1.21.1-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 76f8cb3c8be..484601bb46b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.0' + version = '1.21.1-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 4a48257b215..879d7232285 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.0' + version = '1.21.1-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 8db3c7dc179..cb0026c8ab6 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.0' + version = '1.21.1-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 83317db3b86..4531fa1fd52 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.0' + version = '1.21.1-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 96af492c9d9..bab2565d93f 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.0 - 1.21.0 + 1.21.1RC1 + 1.21.1RC1 - stable - stable + beta + beta Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 10801e5b713..e57b20e0345 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.0"; } +grpc::string Version() { return "1.21.1-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 494ce145dac..76404a70b05 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.0.0"; + public const string CurrentAssemblyFileVersion = "1.21.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.0"; + public const string CurrentVersion = "1.21.1-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index fe280590fd6..9cf56e62028 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.0 + 1.21.1-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 6cfe3a1ab8e..05a236e8bc8 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.0 +set VERSION=1.21.1-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 77d6d4842eb..4c5759acf21 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.0' + v = '1.21.1-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 4686dc2d1b7..adaed0e8069 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0" +#define GRPC_OBJC_VERSION_STRING @"1.21.1-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 30f9ad18021..4995d24b035 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.0" +#define GRPC_OBJC_VERSION_STRING @"1.21.1-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index a9d0aebffca..3171442cc03 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.0", + "version": "1.21.1", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 33adae484ea..e8b9c89cf0d 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.0" +#define PHP_GRPC_VERSION "1.21.1RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 2b68fd5ff04..47cc5285ffa 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.0""" +__version__ = """1.21.1rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index cba5f3c0ebd..190dd3742fa 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 29a7523e926..503642e0de7 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 80257d78a5d..f30051b73eb 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index bf61f4576a9..33990f871c7 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 850704d2f99..ef6fb804fe6 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 2a6b1c4b65a..ca3e64b5334 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 73cbe3913f6..40978182efe 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 272a05310d6..b2c5f8f7085 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.0' + VERSION = '1.21.1.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 3f1c59e3592..b27d73529a6 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.0' + VERSION = '1.21.1.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 5577597ef5d..b0f145cff90 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.0' +VERSION = '1.21.1rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index ac397ab8202..08250515ecf 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0 +PROJECT_NUMBER = 1.21.1-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e0ffeff6650..91ad7a334ef 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.0 +PROJECT_NUMBER = 1.21.1-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 0b50670b23999a1c5451daccf9a14fdf01219c92 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 22 May 2019 12:39:22 -0700 Subject: [PATCH 102/676] Make some test fixes --- tools/run_tests/generated/sources_and_headers.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 34004d7d52d..852119f8e25 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10321,6 +10321,7 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -10447,6 +10448,7 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", From 5ffb32c069ab0aa2e99eaeb1b5e3e432c8f8489a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 22 May 2019 13:43:07 -0700 Subject: [PATCH 103/676] Fix clang errors --- tools/run_tests/generated/sources_and_headers.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 852119f8e25..34004d7d52d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10321,7 +10321,6 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", - "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -10448,7 +10447,6 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", - "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", From e1f62278e316d8b20dc5a2d7f91f76b117d6199b Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 22 May 2019 13:53:10 -0700 Subject: [PATCH 104/676] Fix clang error --- test/cpp/microbenchmarks/bm_cq.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 1f0b9621b21..6ab4b083c13 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -210,8 +210,7 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { gpr_mu_lock(&shutdown_mu); while (!got_shutdown) { // Wait for the shutdown callback to complete. - gpr_cv_wait(&shutdown_cv, &shutdown_mu, - gpr_inf_future(GPR_CLOCK_REALTIME)); + gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } gpr_mu_unlock(&shutdown_mu); GPR_ASSERT(got_shutdown); From e9ab0e0cd94bc6521921b73f724ac28f49fd2bbd Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 22 May 2019 13:56:50 -0700 Subject: [PATCH 105/676] Ensure twine is installed on Windows --- tools/run_tests/artifacts/build_artifact_python.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/build_artifact_python.bat b/tools/run_tests/artifacts/build_artifact_python.bat index e160a101228..c946cd98061 100644 --- a/tools/run_tests/artifacts/build_artifact_python.bat +++ b/tools/run_tests/artifacts/build_artifact_python.bat @@ -47,7 +47,7 @@ python setup.py bdist_wheel || goto :error popd @rem Ensure the generate artifacts are valid. -pip install twine +python -m pip install twine python -m twine check dist\* tools\distrib\python\grpcio_tools\dist\* || goto :error xcopy /Y /I /S dist\* %ARTIFACT_DIR% || goto :error From 3d258e89aec313c2b3687a38eb06cc61559a1cda Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 22 May 2019 14:59:33 -0700 Subject: [PATCH 106/676] Fix windows compiler errors --- test/core/surface/completion_queue_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index ff6722ffb17..4a33b934f43 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -360,7 +360,7 @@ static void test_pluck_after_shutdown(void) { static void test_callback(void) { grpc_completion_queue* cc; - void* tags[128]; + static void* tags[128]; grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; grpc_cq_polling_type polling_types[] = { GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING}; From edc506849f3429c6b4a6d90ec604aeb1b7b0eb54 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Wed, 22 May 2019 15:24:33 -0700 Subject: [PATCH 107/676] Expose interop test for others --- src/proto/grpc/testing/BUILD | 25 ++++++++----- test/cpp/interop/BUILD | 21 ++++++++++- test/cpp/util/BUILD | 1 + test/cpp/util/test_credentials_provider.cc | 43 ++++++++++++++++++++-- 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 727c99cf99c..212f0f3cca7 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -18,11 +18,17 @@ load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:python_rules.bzl", "py_proto_library") -grpc_package(name = "testing", visibility = "public") +grpc_package( + name = "testing", + visibility = "public", +) exports_files([ "echo.proto", "echo_messages.proto", + "test.proto", + "empty.proto", + "messages.proto", ]) grpc_proto_library( @@ -50,9 +56,11 @@ grpc_proto_library( grpc_proto_library( name = "echo_proto", srcs = ["echo.proto"], - deps = ["echo_messages_proto", - "simple_messages_proto"], generate_mocks = True, + deps = [ + "echo_messages_proto", + "simple_messages_proto", + ], ) grpc_proto_library( @@ -102,7 +110,7 @@ grpc_proto_library( name = "benchmark_service_proto", srcs = ["benchmark_service.proto"], deps = [ - "messages_proto", + "messages_proto", ], ) @@ -110,7 +118,7 @@ grpc_proto_library( name = "report_qps_scenario_service_proto", srcs = ["report_qps_scenario_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -118,7 +126,7 @@ grpc_proto_library( name = "worker_service_proto", srcs = ["worker_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -134,7 +142,7 @@ grpc_proto_library( has_services = False, deps = [ "//src/proto/grpc/core:stats_proto", - ] + ], ) grpc_proto_library( @@ -190,6 +198,5 @@ py_proto_library( name = "py_test_proto", deps = [ ":test_proto_descriptor", - ] + ], ) - diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 6cf4719c17b..802302bc8bf 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -16,7 +16,10 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") -grpc_package(name = "test/cpp/interop") +grpc_package( + name = "test/cpp/interop", + visibility = "public", +) grpc_cc_library( name = "server_helper_lib", @@ -103,6 +106,20 @@ grpc_cc_binary( ], ) +grpc_cc_binary( + name = "metrics_client", + srcs = ["metrics_client.cc"], + external_deps = [ + "gflags", + ], + language = "C++", + deps = [ + "//:grpc++", + "//test/cpp/util:metrics_server_lib", + "//test/cpp/util:test_config", + ], +) + grpc_cc_binary( name = "reconnect_interop_client", srcs = [ @@ -153,6 +170,7 @@ grpc_cc_test( external_deps = [ "gflags", ], + tags = ["no_windows"], deps = [ "//:gpr", "//:grpc", @@ -161,5 +179,4 @@ grpc_cc_test( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], - tags = ["no_windows"], ) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index bb1ca868ffb..d112611ef35 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -75,6 +75,7 @@ grpc_cc_library( "test_credentials_provider.h", ], external_deps = [ + "gflags", "protobuf", ], deps = [ diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 455f94e33d4..41779327cb9 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -19,21 +19,50 @@ #include "test/cpp/util/test_credentials_provider.h" +#include +#include +#include + #include #include +#include #include #include #include #include "test/core/end2end/data/ssl_test_data.h" +DEFINE_string(tls_cert_file, "", "The TLS cert file used when --use_tls=true"); +DEFINE_string(tls_key_file, "", "The TLS key file used when --use_tls=true"); + namespace grpc { namespace testing { namespace { +grpc::string ReadFile(const grpc::string& src_path) { + std::ifstream src; + src.open(src_path, std::ifstream::in | std::ifstream::binary); + + grpc::string contents; + src.seekg(0, std::ios::end); + contents.reserve(src.tellg()); + src.seekg(0, std::ios::beg); + contents.assign((std::istreambuf_iterator(src)), + (std::istreambuf_iterator())); + return contents; +} + class DefaultCredentialsProvider : public CredentialsProvider { public: + DefaultCredentialsProvider() { + if (!FLAGS_tls_key_file.empty()) { + custom_server_key_ = ReadFile(FLAGS_tls_key_file); + } + if (!FLAGS_tls_cert_file.empty()) { + custom_server_cert_ = ReadFile(FLAGS_tls_cert_file); + } + } ~DefaultCredentialsProvider() override {} void AddSecureType( @@ -87,11 +116,17 @@ class DefaultCredentialsProvider : public CredentialsProvider { grpc::experimental::AltsServerCredentialsOptions alts_opts; return grpc::experimental::AltsServerCredentials(alts_opts); } else if (type == grpc::testing::kTlsCredentialsType) { - SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, - test_server1_cert}; SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); + if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { + SslServerCredentialsOptions::PemKeyCertPair pkcp = {custom_server_key_, + custom_server_cert_}; + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + } else { + SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, + test_server1_cert}; + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + } return SslServerCredentials(ssl_opts); } else { std::unique_lock lock(mu_); @@ -121,6 +156,8 @@ class DefaultCredentialsProvider : public CredentialsProvider { std::vector added_secure_type_names_; std::vector> added_secure_type_providers_; + grpc::string custom_server_key_; + grpc::string custom_server_cert_; }; CredentialsProvider* g_provider = nullptr; From 8d058dc02077d32d9474211228284e3727bfe969 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 22 May 2019 16:15:47 -0700 Subject: [PATCH 108/676] Correct include style --- src/core/lib/transport/metadata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 3ff5a35dd2d..f59476ccc21 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -21,7 +21,7 @@ #include -#include "include/grpc/impl/codegen/log.h" +#include #include #include From 8a167a7f3994de009f7572376b6492268ec7d172 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Wed, 22 May 2019 16:44:29 -0700 Subject: [PATCH 109/676] Add grpc-java 1.21.0 to client_matrix.py --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 234c71295b3..f19e9399af1 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -148,6 +148,7 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo()), ('v1.19.0', ReleaseInfo()), ('v1.20.0', ReleaseInfo()), + ('v1.21.0', ReleaseInfo()), ]), 'python': OrderedDict([ From 7dae1b919b0c78b7b492ef57b66779a20e7ee262 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 22 May 2019 16:56:03 -0700 Subject: [PATCH 110/676] And the same on Posix systems --- tools/run_tests/artifacts/build_artifact_python.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index e35a3b67bb4..df4fcdbbe3c 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -131,7 +131,7 @@ then fi # Ensure the generated artifacts are valid. -"${PIP}" install twine +"${PYTHON}" -m pip install twine "${PYTHON}" -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* cp -r dist/* "$ARTIFACT_DIR" From 3693fe84cf7e3e728f6d45064ef10942fb88cbe6 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Wed, 22 May 2019 22:37:15 -0700 Subject: [PATCH 111/676] Update comment on ssl hotname override --- include/grpcpp/support/channel_arguments_impl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 0efeadca880..ac3b6c4a7e2 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -61,8 +61,8 @@ class ChannelArguments { void SetChannelArgs(grpc_channel_args* channel_args) const; // gRPC specific channel argument setters - /// Set target name override for SSL host name checking. This option is for - /// testing only and should never be used in production. + /// Set target name override for SSL host name checking. This option should + /// be used with caution in production. void SetSslTargetNameOverride(const grpc::string& name); // TODO(yangg) add flow control options /// Set the compression algorithm for the channel. From 019e9a432b82bd415483c406c36418097e95d2c8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 10:45:23 +0200 Subject: [PATCH 112/676] use kokoro env variable to get the PRs target branch --- .../internal_ci/helper_scripts/prepare_build_linux_perf_rc | 6 ------ tools/internal_ci/helper_scripts/prepare_build_macos_rc | 5 +---- tools/internal_ci/helper_scripts/prepare_build_windows.bat | 5 +---- tools/internal_ci/linux/grpc_microbenchmark_diff.sh | 4 ++-- tools/internal_ci/linux/grpc_run_tests_matrix.sh | 5 +---- tools/internal_ci/linux/grpc_trickle_diff.sh | 2 +- tools/internal_ci/linux/run_if_c_cpp_modified.sh | 4 +--- tools/internal_ci/macos/grpc_ios_binary_size.sh | 2 +- 8 files changed, 8 insertions(+), 25 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index ff5593e031a..bd8c30041c2 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -19,12 +19,6 @@ ulimit -n 32768 ulimit -c unlimited -# Performance PR testing needs GH API key and PR metadata to comment results -if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - sudo apt-get install -y jq - export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) -fi - sudo pip install tabulate # Python dependencies for tools/run_tests/python_utils/check_on_pr.py diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index e9ec07cd0f9..b8f37560148 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -25,10 +25,7 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - brew update - brew install jq || brew upgrade jq - ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) - export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" + export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" fi set +ex # rvm script is very verbose and exits with errorcode diff --git a/tools/internal_ci/helper_scripts/prepare_build_windows.bat b/tools/internal_ci/helper_scripts/prepare_build_windows.bat index bee59159331..c27710ffba4 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_windows.bat +++ b/tools/internal_ci/helper_scripts/prepare_build_windows.bat @@ -18,10 +18,7 @@ set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% @rem If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if defined KOKORO_GITHUB_PULL_REQUEST_NUMBER if defined RUN_TESTS_FLAGS ( - chocolatey install -y jq - for /f "usebackq delims=" %%x in (`curl -s https://api.github.com/repos/grpc/grpc/pulls/%KOKORO_GITHUB_PULL_REQUEST_NUMBER% ^| jq -r .base.ref`) do ( - set RUN_TESTS_FLAGS=%RUN_TESTS_FLAGS% --filter_pr_tests --base_branch origin/%%x - ) + set RUN_TESTS_FLAGS=%RUN_TESTS_FLAGS% --filter_pr_tests --base_branch origin/%KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH% ) @rem Update DNS settings to: diff --git a/tools/internal_ci/linux/grpc_microbenchmark_diff.sh b/tools/internal_ci/linux/grpc_microbenchmark_diff.sh index 9834aaa0534..c03383d1461 100755 --- a/tools/internal_ci/linux/grpc_microbenchmark_diff.sh +++ b/tools/internal_ci/linux/grpc_microbenchmark_diff.sh @@ -26,9 +26,9 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc tools/run_tests/start_port_server.py tools/internal_ci/linux/run_if_c_cpp_modified.sh tools/profiling/bloat/bloat_diff.py \ - -d origin/$ghprbTargetBranch || FAILED="true" + -d "origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" || FAILED="true" tools/internal_ci/linux/run_if_c_cpp_modified.sh tools/profiling/microbenchmarks/bm_diff/bm_main.py \ - -d origin/$ghprbTargetBranch \ + -d "origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" \ -b $BENCHMARKS_TO_RUN || FAILED="true" # kill port_server.py to prevent the build from hanging diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index f9acd814ae8..a0ce71aeb7d 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -22,10 +22,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then - sudo apt-get update - sudo apt-get install -y jq - ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) - export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" + export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" fi tools/run_tests/run_tests_matrix.py $RUN_TESTS_FLAGS || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_trickle_diff.sh b/tools/internal_ci/linux/grpc_trickle_diff.sh index 4ed1b73f9e8..49c3d4b2db0 100755 --- a/tools/internal_ci/linux/grpc_trickle_diff.sh +++ b/tools/internal_ci/linux/grpc_trickle_diff.sh @@ -26,7 +26,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc tools/run_tests/start_port_server.py tools/internal_ci/linux/run_if_c_cpp_modified.sh tools/profiling/microbenchmarks/bm_diff/bm_main.py \ - -d origin/$ghprbTargetBranch \ + -d "origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" \ -b bm_fullstack_trickle \ -l 4 \ -t $BENCHMARKS_TO_RUN \ diff --git a/tools/internal_ci/linux/run_if_c_cpp_modified.sh b/tools/internal_ci/linux/run_if_c_cpp_modified.sh index 736d7594234..2414dcca7c9 100755 --- a/tools/internal_ci/linux/run_if_c_cpp_modified.sh +++ b/tools/internal_ci/linux/run_if_c_cpp_modified.sh @@ -20,13 +20,11 @@ set -ex # Enter the gRPC repo root cd $(dirname $0)/../../.. -# TODO(jtattermusch): the "ghprbTargetBranch" is Jenkins specific and probably -# does not work on kokoro? AFFECTS_C_CPP=`python -c 'import os; \ import sys; \ sys.path.insert(0, "tools/run_tests/python_utils"); \ import filter_pull_request_tests as filter; \ - github_target_branch = os.environ.get("ghprbTargetBranch"); \ + github_target_branch = os.environ.get("KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH"); \ print(filter.affects_c_cpp("origin/%s" % github_target_branch))'` if [ $AFFECTS_C_CPP == "False" ] ; then diff --git a/tools/internal_ci/macos/grpc_ios_binary_size.sh b/tools/internal_ci/macos/grpc_ios_binary_size.sh index ea39b0d6e94..17937a30d41 100755 --- a/tools/internal_ci/macos/grpc_ios_binary_size.sh +++ b/tools/internal_ci/macos/grpc_ios_binary_size.sh @@ -24,4 +24,4 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_macos_rc tools/profiling/ios_bin/binary_size.py \ - -d origin/$ghprbTargetBranch + -d "origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" From b53e707c3c155171d746e99e7020f311f0af3d8b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 17:54:40 +0200 Subject: [PATCH 113/676] update bazel version in dockerfile --- templates/tools/dockerfile/bazel.include | 9 ++++++--- tools/dockerfile/test/bazel/Dockerfile | 9 ++++++--- tools/dockerfile/test/sanity/Dockerfile | 9 ++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index 8888e938f43..3744dacc281 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -1,7 +1,10 @@ #======================== # Bazel installation +# Must be in sync with tools/bazel.sh +ENV BAZEL_VERSION 0.24.1 + RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} - bash ./bazel-0.23.2-installer-linux-x86_64.sh && ${'\\'} - rm bazel-0.23.2-installer-linux-x86_64.sh +RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && ${'\\'} + bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && ${'\\'} + rm bazel-$BAZEL_VERSION-installer-linux-x86_64.sh diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 2536fe299cb..b9fc409d939 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -51,10 +51,13 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #======================== # Bazel installation +# Must be in sync with tools/bazel.sh +ENV BAZEL_VERSION 0.24.1 + RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ - bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ - rm bazel-0.23.2-installer-linux-x86_64.sh +RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && \ + bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \ + rm bazel-$BAZEL_VERSION-installer-linux-x86_64.sh RUN mkdir -p /var/local/jenkins diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index 765bd7267a4..4ef4a0a9454 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -97,10 +97,13 @@ ENV CLANG_TIDY=clang-tidy #======================== # Bazel installation +# Must be in sync with tools/bazel.sh +ENV BAZEL_VERSION 0.24.1 + RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-installer-linux-x86_64.sh && \ - bash ./bazel-0.23.2-installer-linux-x86_64.sh && \ - rm bazel-0.23.2-installer-linux-x86_64.sh +RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && \ + bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \ + rm bazel-$BAZEL_VERSION-installer-linux-x86_64.sh # Define the default command. From a651957c94f871ae2a429df80e1a7d4ab30e221f Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 23 May 2019 09:41:29 -0700 Subject: [PATCH 114/676] Use a virtual environment --- tools/run_tests/artifacts/build_artifact_python.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index df4fcdbbe3c..9af11980eba 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -131,8 +131,10 @@ then fi # Ensure the generated artifacts are valid. -"${PYTHON}" -m pip install twine -"${PYTHON}" -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* +"${PYTHON}" -m virtualenv venv +venv/bin/python -m pip install twine +venv/bin/python -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* +rm -rf venv/ cp -r dist/* "$ARTIFACT_DIR" cp -r tools/distrib/python/grpcio_tools/dist/* "$ARTIFACT_DIR" From 374ff3139a955b5df1fdb10b7a4cf228f597e1eb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 17:56:52 +0200 Subject: [PATCH 115/676] use bazel.sh for foundry RBE tests --- .../internal_ci/linux/grpc_bazel_on_foundry_base.sh | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 93399f81e79..bcde79ecd8e 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -15,26 +15,21 @@ set -ex -# Download bazel -temp_dir="$(mktemp -d)" -wget -q https://github.com/bazelbuild/bazel/releases/download/0.23.2/bazel-0.23.2-linux-x86_64 -O "${temp_dir}/bazel" -chmod 755 "${temp_dir}/bazel" -export PATH="${temp_dir}:${PATH}" -# This should show ${temp_dir}/bazel -which bazel - # change to grpc repo root cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc +# make sure bazel is available +tools/bazel.sh version + # to get "bazel" link for kokoro build, we need to generate # invocation UUID, set a flag for bazel to use it # and upload "bazel_invocation_ids" file as artifact. BAZEL_INVOCATION_ID="$(uuidgen)" echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" -bazel \ +tools/bazel.sh \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ --invocation_id="${BAZEL_INVOCATION_ID}" \ From a3cc5ee574ca0e4c059ff353616ea307894aa223 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 17:57:52 +0200 Subject: [PATCH 116/676] use bazel.sh in bazel RBE readme --- tools/remote_build/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index 2cd5f03daf1..4cc3c7a0ea1 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -17,22 +17,27 @@ and tests run by Kokoro CI. ## Running remote build manually from dev workstation +*At the time being, tools/bazel.sh is used instead of invoking "bazel" directly +to overcome the bazel versioning problem (our BUILD files currently only work with +a specific window of bazel version and bazel.sh wrapper makes sure that version +is used).* + Run from repository root (opt, dbg): ``` # manual run of bazel tests remotely on Foundry -bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/... +tools/bazel.sh --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/... ``` Sanitizer runs (asan, msan, tsan, ubsan): ``` # manual run of bazel tests remotely on Foundry with given sanitizer -bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... +tools/bazel.sh --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... ``` Run on Windows MSVC: ``` # RBE manual run only for c-core (must be run on a Windows host machine) -bazel --bazelrc=tools/remote_build/windows.bazelrc build :all [--credentials_json=(path to service account credentials)] +tools/bazel.sh --bazelrc=tools/remote_build/windows.bazelrc build :all [--credentials_json=(path to service account credentials)] ``` Available command line options can be found in From af279949d49109ee54d484b345abe5b78b8614ea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 18:16:03 +0200 Subject: [PATCH 117/676] update bazel_rbe.bat --- tools/internal_ci/windows/bazel_rbe.bat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/internal_ci/windows/bazel_rbe.bat b/tools/internal_ci/windows/bazel_rbe.bat index 8f2c534c5ef..30c66896edf 100644 --- a/tools/internal_ci/windows/bazel_rbe.bat +++ b/tools/internal_ci/windows/bazel_rbe.bat @@ -13,7 +13,8 @@ @rem limitations under the License. @rem TODO(jtattermusch): make this generate less output -choco install bazel -y --version 0.23.2 --limit-output +@rem TODO(jtattermusch): use tools/bazel.sh script to keep the versions in sync +choco install bazel -y --version 0.24.1 --limit-output cd github/grpc set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH% From d721b3ac1e8a6c1d915167733e0dccb00c262cd4 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 23 May 2019 10:38:57 -0700 Subject: [PATCH 118/676] Compensate for no virtualenv module on Linux kokoro workers --- tools/run_tests/artifacts/build_artifact_python.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index 9af11980eba..c5e380fe5dc 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -131,7 +131,7 @@ then fi # Ensure the generated artifacts are valid. -"${PYTHON}" -m virtualenv venv +"${PYTHON}" -m virtualenv venv || { "${PYTHON}" -m pip install virtualenv && "${PYTHON}" -m virtualenv venv; } venv/bin/python -m pip install twine venv/bin/python -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* rm -rf venv/ From 0cafd4110aa47645996d61739750cabe313937b9 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 23 May 2019 11:12:08 -0700 Subject: [PATCH 119/676] Fix typo --- include/grpcpp/impl/codegen/completion_queue_impl.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index 5435f2fa165..d5c4bb0f201 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -186,8 +186,8 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { /// within the \a deadline). A \a tag points to an arbitrary location usually /// employed to uniquely identify an event. /// - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if a successful event, false otherwise + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if a successful event, false otherwise /// See documentation for CompletionQueue::Next for explanation of ok /// \param deadline [in] How long to block in wait for an event. /// @@ -206,8 +206,8 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { /// employed to uniquely identify an event. /// /// \param f [in] Function to execute before calling AsyncNext on this queue. - /// \param tag [out] Upon sucess, updated to point to the event's tag. - /// \param ok [out] Upon sucess, true if read a regular event, false + /// \param tag [out] Upon success, updated to point to the event's tag. + /// \param ok [out] Upon success, true if read a regular event, false /// otherwise. /// \param deadline [in] How long to block in wait for an event. /// From 1ac1ab73965bebb6f7a5850bf62245a390c31ad6 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Mon, 20 May 2019 12:24:47 -0700 Subject: [PATCH 120/676] Flaky network test enhancements and cleanups - Parameterized flaky_network_test to run with different packet sizes and credentials. - Cleanup debugger_macros Parametrize flaky_network_test to run with different packet sizes and credentials. --- .../test/core/end2end/end2end_defs.include | 2 - test/core/end2end/end2end_nosec_tests.cc | 2 - test/core/end2end/end2end_tests.cc | 2 - test/core/util/debugger_macros.cc | 3 - test/core/util/debugger_macros.h | 5 +- test/cpp/end2end/flaky_network_test.cc | 115 +++++++++++++----- .../linux/grpc_flaky_network_in_docker.sh | 2 +- 7 files changed, 89 insertions(+), 42 deletions(-) diff --git a/templates/test/core/end2end/end2end_defs.include b/templates/test/core/end2end/end2end_defs.include index d40ba2065be..91fa1d9502a 100644 --- a/templates/test/core/end2end/end2end_defs.include +++ b/templates/test/core/end2end/end2end_defs.include @@ -27,7 +27,6 @@ #include -#include "test/core/util/debugger_macros.h" static bool g_pre_init_called = false; @@ -39,7 +38,6 @@ extern void ${test}_pre_init(void); void grpc_end2end_tests_pre_init(void) { GPR_ASSERT(!g_pre_init_called); g_pre_init_called = true; - grpc_summon_debugger_macros(); % for test in tests: ${test}_pre_init(); % endfor diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index 3ab55527da6..e01e6ad0104 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -26,7 +26,6 @@ #include -#include "test/core/util/debugger_macros.h" static bool g_pre_init_called = false; @@ -188,7 +187,6 @@ extern void write_buffering_at_end_pre_init(void); void grpc_end2end_tests_pre_init(void) { GPR_ASSERT(!g_pre_init_called); g_pre_init_called = true; - grpc_summon_debugger_macros(); authority_not_supported_pre_init(); bad_hostname_pre_init(); bad_ping_pre_init(); diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index b680da4433f..76fb046b367 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -26,7 +26,6 @@ #include -#include "test/core/util/debugger_macros.h" static bool g_pre_init_called = false; @@ -190,7 +189,6 @@ extern void write_buffering_at_end_pre_init(void); void grpc_end2end_tests_pre_init(void) { GPR_ASSERT(!g_pre_init_called); g_pre_init_called = true; - grpc_summon_debugger_macros(); authority_not_supported_pre_init(); bad_hostname_pre_init(); bad_ping_pre_init(); diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index fed6ad97285..fde68f32178 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -21,7 +21,6 @@ * Not intended to be robust for main-line code, often cuts across abstraction * boundaries. */ - #include #include "src/core/ext/filters/client_channel/client_channel.h" @@ -29,8 +28,6 @@ #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/surface/call.h" -void grpc_summon_debugger_macros() {} - grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { grpc_call_stack* cs = grpc_call_get_call_stack(call); for (;;) { diff --git a/test/core/util/debugger_macros.h b/test/core/util/debugger_macros.h index c6b3720c5ad..71228c6e875 100644 --- a/test/core/util/debugger_macros.h +++ b/test/core/util/debugger_macros.h @@ -19,6 +19,9 @@ #ifndef GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H #define GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H -void grpc_summon_debugger_macros(); +#include "src/core/ext/transport/chttp2/transport/internal.h" +#include "src/core/lib/surface/call.h" + +grpc_chttp2_stream* grpc_chttp2_stream_from_call(grpc_call* call); #endif /* GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H */ diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc index 63a6897f931..626b5a56226 100644 --- a/test/cpp/end2end/flaky_network_test.cc +++ b/test/cpp/end2end/flaky_network_test.cc @@ -16,12 +16,6 @@ * */ -#include -#include -#include -#include -#include - #include #include #include @@ -35,16 +29,22 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" - #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/debugger_macros.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" - -#include +#include "test/cpp/util/test_credentials_provider.h" #ifdef GPR_LINUX using grpc::testing::EchoRequest; @@ -54,14 +54,20 @@ namespace grpc { namespace testing { namespace { -class FlakyNetworkTest : public ::testing::Test { +struct TestScenario { + TestScenario(const grpc::string& creds_type, const grpc::string& content) + : credentials_type(creds_type), message_content(content) {} + const grpc::string credentials_type; + const grpc::string message_content; +}; + +class FlakyNetworkTest : public ::testing::TestWithParam { protected: FlakyNetworkTest() : server_host_("grpctest"), interface_("lo:1"), ipv4_address_("10.0.0.1"), - netmask_("/32"), - kRequestMessage_("🖖") {} + netmask_("/32") {} void InterfaceUp() { std::ostringstream cmd; @@ -129,10 +135,11 @@ class FlakyNetworkTest : public ::testing::Test { void FlakeNetwork() { std::ostringstream cmd; // Emulate a flaky network connection over interface_. Add a delay of 100ms - // +/- 590ms, 3% packet loss, 1% duplicates and 0.1% corrupt packets. + // +/- 20ms, 0.1% packet loss, 1% duplicates and 0.01% corrupt packets. cmd << "tc qdisc replace dev " << interface_ - << " root netem delay 100ms 50ms distribution normal loss 3% duplicate " - "1% corrupt 0.1% "; + << " root netem delay 100ms 20ms distribution normal loss 0.1% " + "duplicate " + "0.1% corrupt 0.01% "; std::system(cmd.str().c_str()); } @@ -172,7 +179,7 @@ class FlakyNetworkTest : public ::testing::Test { // ip6-looopback, but ipv6 support is not enabled by default in docker. port_ = SERVER_PORT; - server_.reset(new ServerData(port_)); + server_.reset(new ServerData(port_, GetParam().credentials_type)); server_->Start(server_host_); } void StopServer() { server_->Shutdown(); } @@ -188,10 +195,11 @@ class FlakyNetworkTest : public ::testing::Test { if (lb_policy_name.size() > 0) { args.SetLoadBalancingPolicyName(lb_policy_name); } // else, default to pick first + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); std::ostringstream server_address; server_address << server_host_ << ":" << port_; - return CreateCustomChannel(server_address.str(), - InsecureChannelCredentials(), args); + return CreateCustomChannel(server_address.str(), channel_creds, args); } bool SendRpc( @@ -199,7 +207,8 @@ class FlakyNetworkTest : public ::testing::Test { int timeout_ms = 0, bool wait_for_ready = false) { auto response = std::unique_ptr(new EchoResponse()); EchoRequest request; - request.set_message(kRequestMessage_); + auto& msg = GetParam().message_content; + request.set_message(msg); ClientContext context; if (timeout_ms > 0) { context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); @@ -211,22 +220,33 @@ class FlakyNetworkTest : public ::testing::Test { } Status status = stub->Echo(&context, request, response.get()); auto ok = status.ok(); + int stream_id = 0; + grpc_call* call = context.c_call(); + if (call) { + grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); + if (stream) { + stream_id = stream->id; + } + } if (ok) { - gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, + status.error_message().c_str()); } return ok; } struct ServerData { int port_; + const grpc::string creds_; std::unique_ptr server_; TestServiceImpl service_; std::unique_ptr thread_; bool server_ready_ = false; - explicit ServerData(int port) { port_ = port; } + ServerData(int port, const grpc::string& creds) + : port_(port), creds_(creds) {} void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); @@ -245,8 +265,9 @@ class FlakyNetworkTest : public ::testing::Test { std::ostringstream server_address; server_address << server_host << ":" << port_; ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(creds_); + builder.AddListeningPort(server_address.str(), server_creds); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); std::lock_guard lock(*mu); @@ -291,11 +312,43 @@ class FlakyNetworkTest : public ::testing::Test { std::unique_ptr server_; const int SERVER_PORT = 32750; int port_; - const grpc::string kRequestMessage_; }; +std::vector CreateTestScenarios() { + std::vector scenarios; + std::vector credentials_types; + std::vector messages; + + credentials_types.push_back(kInsecureCredentialsType); + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + + messages.push_back("🖖"); + for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { + grpc::string big_msg; + for (size_t i = 0; i < k * 1024; ++i) { + char c = 'a' + (i % 26); + big_msg += c; + } + messages.push_back(big_msg); + } + for (auto cred = credentials_types.begin(); cred != credentials_types.end(); + ++cred) { + for (auto msg = messages.begin(); msg != messages.end(); msg++) { + scenarios.emplace_back(*cred, *msg); + } + } + + return scenarios; +} + +INSTANTIATE_TEST_CASE_P(FlakyNetworkTest, FlakyNetworkTest, + ::testing::ValuesIn(CreateTestScenarios())); + // Network interface connected to server flaps -TEST_F(FlakyNetworkTest, NetworkTransition) { +TEST_P(FlakyNetworkTest, NetworkTransition) { const int kKeepAliveTimeMs = 1000; const int kKeepAliveTimeoutMs = 1000; ChannelArguments args; @@ -336,7 +389,7 @@ TEST_F(FlakyNetworkTest, NetworkTransition) { } // Traffic to server server is blackholed temporarily with keepalives enabled -TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { +TEST_P(FlakyNetworkTest, ServerUnreachableWithKeepalive) { const int kKeepAliveTimeMs = 1000; const int kKeepAliveTimeoutMs = 1000; const int kReconnectBackoffMs = 1000; @@ -385,7 +438,7 @@ TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { // // Traffic to server server is blackholed temporarily with keepalives disabled -TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { +TEST_P(FlakyNetworkTest, ServerUnreachableNoKeepalive) { auto channel = BuildChannel("pick_first", ChannelArguments()); auto stub = BuildStub(channel); // Channel should be in READY state after we send an RPC @@ -411,7 +464,7 @@ TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { } // Send RPCs over a flaky network connection -TEST_F(FlakyNetworkTest, FlakyNetwork) { +TEST_P(FlakyNetworkTest, FlakyNetwork) { const int kKeepAliveTimeMs = 1000; const int kKeepAliveTimeoutMs = 1000; const int kMessageCount = 100; @@ -438,7 +491,7 @@ TEST_F(FlakyNetworkTest, FlakyNetwork) { } // Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_F(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { +TEST_P(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { const int kKeepAliveTimeMs = 1000; const int kKeepAliveTimeoutMs = 1000; ChannelArguments args; @@ -468,7 +521,7 @@ TEST_F(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { } // Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_F(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { +TEST_P(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { auto channel = BuildChannel("pick_first", ChannelArguments()); auto stub = BuildStub(channel); // Channel should be in READY state after we send an RPC diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index 7fc8f146727..d574638d3ef 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -28,4 +28,4 @@ cd /var/local/git/grpc/test/cpp/end2end # iptables is used to drop traffic between client and server apt-get install -y iptables -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test --test_env=GRPC_VERBOSITY=debug --test_env=GRPC_TRACE=channel,client_channel,call_error,connectivity_state,tcp +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all --test_timeout=1200 :flaky_network_test --test_env=GRPC_TRACE=http --test_env=GRPC_VERBOSITY=DEBUG From 796744596864229ffe1d2307e42add2c7b17761c Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 22 May 2019 13:14:53 -0700 Subject: [PATCH 121/676] Fix PHP extension segfault --- src/php/ext/grpc/php_grpc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index f6c2f85ed47..1098075690a 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -205,7 +205,9 @@ void register_fork_handlers() { void apply_ini_settings() { if (GRPC_G(enable_fork_support)) { - putenv("GRPC_ENABLE_FORK_SUPPORT=1"); + char *enable_str = malloc(sizeof("GRPC_ENABLE_FORK_SUPPORT=1")); + strcpy(enable_str, "GRPC_ENABLE_FORK_SUPPORT=1"); + putenv(enable_str); } if (GRPC_G(poll_strategy)) { From fb1a6b1d4804782f8ee9b6e1a563a4397f436714 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 23 May 2019 13:25:04 -0700 Subject: [PATCH 122/676] clang-format --- .../tests/CronetTests/CronetUnitTests.mm | 2 +- src/objective-c/tests/EnableCronet.m | 2 +- .../tests/InteropTests/InteropTests.m | 2 +- .../InteropTestsMultipleChannels.m | 177 ++++++++++-------- 4 files changed, 104 insertions(+), 79 deletions(-) diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index b17bc334479..b0f3a3000f1 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -40,8 +40,8 @@ #import "test/core/util/test_config.h" #define GRPC_SHADOW_BORINGSSL_SYMBOLS -#import "src/core/tsi/grpc_shadow_boringssl.h" #import " +#import "src/core/tsi/grpc_shadow_boringssl.h" static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; diff --git a/src/objective-c/tests/EnableCronet.m b/src/objective-c/tests/EnableCronet.m index b618ec74706..5e0c933d835 100644 --- a/src/objective-c/tests/EnableCronet.m +++ b/src/objective-c/tests/EnableCronet.m @@ -18,8 +18,8 @@ #ifdef GRPC_COMPILE_WITH_CRONET -#import #import "EnableCronet.h" +#import void enableCronet(void) { static dispatch_once_t enableCronet; diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 91fdd0fd841..89f5b96c38b 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -36,8 +36,8 @@ #import #import -#import "InteropTestsBlockCallbacks.h" #import "../EnableCronet.h" +#import "InteropTestsBlockCallbacks.h" #define TEST_TIMEOUT 32 diff --git a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m index 58946825f98..ffda48719e7 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m @@ -26,8 +26,8 @@ #import #import -#import "InteropTestsBlockCallbacks.h" #import "../EnableCronet.h" +#import "InteropTestsBlockCallbacks.h" #define NSStringize_helper(x) #x #define NSStringize(x) @NSStringize_helper(x) @@ -67,8 +67,6 @@ static const NSTimeInterval TEST_TIMEOUT = 8000; } @end - - @interface InteropTestsMultipleChannels : XCTestCase @end @@ -97,7 +95,6 @@ dispatch_once_t initCronet; // Cronet stack with remote host _remoteCronetService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:options]; - // Local stack with no SSL options = [[GRPCMutableCallOptions alloc] init]; options.transportType = GRPCTransportTypeInsecure; @@ -134,42 +131,54 @@ dispatch_once_t initCronet; XCTAssertEqualObjects(message, expectedResponse); }; - GRPCUnaryProtoCall *callRemote = [_remoteService emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:messageHandler - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectRemote fulfill]; - } - writeMessageCallback:nil] - callOptions:nil]; - GRPCUnaryProtoCall *callCronet = [_remoteCronetService emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:messageHandler - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectCronetRemote fulfill]; - } - writeMessageCallback:nil] - callOptions:nil]; - GRPCUnaryProtoCall *callCleartext = [_localCleartextService emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:messageHandler - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectCleartext fulfill]; - } - writeMessageCallback:nil] - callOptions:nil]; - GRPCUnaryProtoCall *callSSL = [_localSSLService emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:messageHandler - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectSSL fulfill]; - } - writeMessageCallback:nil] - callOptions:nil]; + GRPCUnaryProtoCall *callRemote = [_remoteService + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callCronet = [_remoteCronetService + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectCronetRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callCleartext = [_localCleartextService + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectCleartext fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + GRPCUnaryProtoCall *callSSL = [_localSSLService + emptyCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:messageHandler + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectSSL fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; [callRemote start]; [callCronet start]; [callCleartext start]; @@ -219,42 +228,58 @@ dispatch_once_t initCronet; } }; - calls[0] = [_remoteService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - handler(0, message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectRemote fulfill]; - } writeMessageCallback:nil] - callOptions:nil]; - calls[1] = [_remoteCronetService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - handler(1, message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectCronetRemote fulfill]; - } writeMessageCallback:nil] - callOptions:nil]; - calls[2] = [_localCleartextService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - handler(2, message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectCleartext fulfill]; - } writeMessageCallback:nil] - callOptions:nil]; - calls[3] = [_localSSLService fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - handler(3, message); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error); - [expectSSL fulfill]; - } writeMessageCallback:nil] - callOptions:nil]; + calls[0] = [_remoteService + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(0, message); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + calls[1] = [_remoteCronetService + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(1, message); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectCronetRemote fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + calls[2] = [_localCleartextService + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(2, message); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectCleartext fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; + calls[3] = [_localSSLService + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + handler(3, message); + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error); + [expectSSL fulfill]; + } + writeMessageCallback:nil] + callOptions:nil]; for (int i = 0; i < 4; i++) { [calls[i] start]; [calls[i] writeMessage:requests[0]]; From 0a57193dec25db5e5b44e7a7445fb7b0a55fe571 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 23 May 2019 16:11:23 -0700 Subject: [PATCH 123/676] Replaced gpr_ref with grpc_core::Atomic in call batch struct --- src/core/lib/surface/call.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 254476f47e3..271b3ddd560 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -74,7 +74,7 @@ #define ESTIMATED_MDELEM_COUNT 16 struct batch_control { - batch_control() { gpr_ref_init(&steps_to_complete, 0); } + batch_control() = default; grpc_call* call = nullptr; grpc_transport_stream_op_batch op; @@ -99,8 +99,14 @@ struct batch_control { } completion_data; grpc_closure start_batch; grpc_closure finish_batch; - gpr_refcount steps_to_complete; + grpc_core::Atomic steps_to_complete; gpr_atm batch_error = reinterpret_cast(GRPC_ERROR_NONE); + void set_num_steps_to_complete(uintptr_t steps) { + steps_to_complete.Store(steps, grpc_core::MemoryOrder::RELEASE); + } + bool completed_batch_step() { + return steps_to_complete.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1; + } }; struct parent_call { @@ -1225,7 +1231,7 @@ static void post_batch_completion(batch_control* bctl) { } static void finish_batch_step(batch_control* bctl) { - if (GPR_UNLIKELY(gpr_unref(&bctl->steps_to_complete))) { + if (GPR_UNLIKELY(bctl->completed_batch_step())) { post_batch_completion(bctl); } } @@ -1866,7 +1872,7 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, if (!is_notify_tag_closure) { GPR_ASSERT(grpc_cq_begin_op(call->cq, notify_tag)); } - gpr_ref_init(&bctl->steps_to_complete, (has_send_ops ? 1 : 0) + num_recv_ops); + bctl->set_num_steps_to_complete((has_send_ops ? 1 : 0) + num_recv_ops); if (has_send_ops) { GRPC_CLOSURE_INIT(&bctl->finish_batch, finish_batch, bctl, From 1bb3f72abee4e5276b44aded69ce3ee59b478a84 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 23 May 2019 17:08:51 -0700 Subject: [PATCH 124/676] clang-format --- src/objective-c/tests/InteropTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 690c5cee0a2..c96d3436144 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -332,7 +332,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } -- (void)writeData:(id )data { +- (void)writeData:(id)data { if (_writeDataHook) { _writeDataHook(data, _manager); } @@ -356,7 +356,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } -- (void)didReceiveData:(id )data { +- (void)didReceiveData:(id)data { if (_responseDataHook) { _responseDataHook(data, _manager); } From d2c8eb94c954914e14f979229e963964211c80f8 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 23 May 2019 18:09:12 -0700 Subject: [PATCH 125/676] Fix microbenchmark failures --- test/cpp/microbenchmarks/callback_streaming_ping_pong.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 9fb86bd8299..0d27e0efa50 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -115,7 +115,7 @@ class BidiClient int msgs_size_; std::mutex mu; std::condition_variable cv; - bool done; + bool done = false; }; template From b18faa6c95bee22f03730ad4bc9b192440b5403b Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 23 May 2019 20:08:45 -0700 Subject: [PATCH 126/676] Fix tsan error --- test/cpp/microbenchmarks/bm_cq.cc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 6ab4b083c13..edbff9c2be3 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -150,6 +150,9 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { grpc_completion_queue_destroy(cc); } +static gpr_mu shutdown_mu, mu; +static gpr_cv shutdown_cv, cv; + // Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: @@ -158,17 +161,17 @@ class TagCallback : public grpc_experimental_completion_queue_functor { } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&mu); GPR_ASSERT(static_cast(ok)); *static_cast(cb)->iter_ += 1; + gpr_cv_signal(&cv); + gpr_mu_unlock(&mu); }; private: int* iter_; }; -static gpr_mu shutdown_mu; -static gpr_cv shutdown_cv; - // Check if completion queue is shut down class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: @@ -189,8 +192,10 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { TrackCounters track_counters; - int iteration = 0; + int iteration = 0, current_iterations = 0; TagCallback tag_cb(&iteration); + gpr_mu_init(&mu); + gpr_cv_init(&cv); gpr_mu_init(&shutdown_mu); gpr_cv_init(&shutdown_cv); bool got_shutdown = false; @@ -207,15 +212,26 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { } shutdown_and_destroy(cc); + gpr_mu_lock(&mu); + current_iterations = static_cast(state.iterations()); + while (current_iterations != iteration) { + // Wait for all the callbacks to complete. + gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&mu); + gpr_mu_lock(&shutdown_mu); while (!got_shutdown) { // Wait for the shutdown callback to complete. gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } gpr_mu_unlock(&shutdown_mu); + GPR_ASSERT(got_shutdown); GPR_ASSERT(iteration == static_cast(state.iterations())); track_counters.Finish(state); + gpr_cv_destroy(&cv); + gpr_mu_destroy(&mu); gpr_cv_destroy(&shutdown_cv); gpr_mu_destroy(&shutdown_mu); } From 088319bc40f2d0b38c69a7b3c557749131451810 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 23 May 2019 22:10:53 -0700 Subject: [PATCH 127/676] IWYU in core_codegen_interface core_codegen_interface requires ByteBuffer in generated code and needs to include byte_buffer.h NO_BUG=Cleanup --- include/grpcpp/impl/codegen/core_codegen_interface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 3792c3d4693..02b5033c51f 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H #define GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H +#include #include #include #include From a0164889fb251c9b0e0570736241490b7316356b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 24 May 2019 09:19:49 -0700 Subject: [PATCH 128/676] Bump version to v1.21.1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 39777d9f723..c75a5d124fc 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.1-pre1" +version = "1.21.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index b6508734295..0344ce18053 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.1-pre1 + version: 1.21.1 filegroups: - name: alts_proto headers: From 8a01f6340f03bb98e016fabd1c7845dcb3c35d1e Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Fri, 24 May 2019 09:24:35 -0700 Subject: [PATCH 129/676] regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d335591779c..0b0c75c0811 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.1-pre1") +set(PACKAGE_VERSION "1.21.1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 36f3f051dd3..0d148ab3cd2 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.1-pre1 -CSHARP_VERSION = 1.21.1-pre1 +CPP_VERSION = 1.21.1 +CSHARP_VERSION = 1.21.1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4286e3d57e7..ca27e4f34f3 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.1-pre1' - version = '0.0.9-pre1' + # version = '1.21.1' + version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.1-pre1' + grpc_version = '1.21.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 484601bb46b..ca3225b3694 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.1-pre1' + version = '1.21.1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 879d7232285..2012515bbe9 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.1-pre1' + version = '1.21.1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index cb0026c8ab6..c4a9f2889e9 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.1-pre1' + version = '1.21.1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 4531fa1fd52..31a1c448aa1 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.1-pre1' + version = '1.21.1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index bab2565d93f..6bcbd807566 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.1RC1 - 1.21.1RC1 + 1.21.1 + 1.21.1 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index e57b20e0345..619220ce4e3 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.1-pre1"; } +grpc::string Version() { return "1.21.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 76404a70b05..5cf75df63ab 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.1-pre1"; + public const string CurrentVersion = "1.21.1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 9cf56e62028..c4c40fe0c66 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.1-pre1 + 1.21.1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 05a236e8bc8..65deb40679c 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.1-pre1 +set VERSION=1.21.1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 4c5759acf21..8ac2dd7d303 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.1-pre1' + v = '1.21.1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index adaed0e8069..e410f8da012 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 4995d24b035..95b112b156f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index e8b9c89cf0d..07a73698015 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.1RC1" +#define PHP_GRPC_VERSION "1.21.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 47cc5285ffa..4624e467fd8 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.1rc1""" +__version__ = """1.21.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 190dd3742fa..2451ef4a538 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 503642e0de7..591b5bd8fc5 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index f30051b73eb..c11487af7e8 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 33990f871c7..47628416c26 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index ef6fb804fe6..713746a1598 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index ca3e64b5334..3fe457f304c 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 40978182efe..103b532f38f 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index b2c5f8f7085..1308aa4652e 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.1.pre1' + VERSION = '1.21.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index b27d73529a6..38f7129d139 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.1.pre1' + VERSION = '1.21.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index b0f145cff90..872f821c2f6 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.1rc1' +VERSION = '1.21.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 08250515ecf..c683fe91df1 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1-pre1 +PROJECT_NUMBER = 1.21.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 91ad7a334ef..69f6a345afa 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1-pre1 +PROJECT_NUMBER = 1.21.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From caa965bd1d0b12e388cd95da5593880049675b1b Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 May 2019 09:25:17 -0700 Subject: [PATCH 130/676] Address comments --- .../{EnableCronet.h => ConfigureCronet.h} | 2 +- .../{EnableCronet.m => ConfigureCronet.m} | 10 ++--- .../CronetTests/CoreCronetEnd2EndTests.mm | 4 +- .../tests/CronetTests/CronetUnitTests.mm | 6 +-- .../tests/InteropTests/InteropTests.m | 4 +- .../InteropTestsMultipleChannels.m | 4 +- src/objective-c/tests/Podfile | 26 ++++++------- .../tests/Tests.xcodeproj/project.pbxproj | 37 +++++-------------- .../xcschemes/InteropTests.xcscheme | 2 +- 9 files changed, 36 insertions(+), 59 deletions(-) rename src/objective-c/tests/{EnableCronet.h => ConfigureCronet.h} (96%) rename src/objective-c/tests/{EnableCronet.m => ConfigureCronet.m} (86%) diff --git a/src/objective-c/tests/EnableCronet.h b/src/objective-c/tests/ConfigureCronet.h similarity index 96% rename from src/objective-c/tests/EnableCronet.h rename to src/objective-c/tests/ConfigureCronet.h index 720aace4075..cc5c038f3c6 100644 --- a/src/objective-c/tests/EnableCronet.h +++ b/src/objective-c/tests/ConfigureCronet.h @@ -25,7 +25,7 @@ extern "C" { /** * Enable Cronet for once. */ -void enableCronet(void); +void configureCronet(void); #ifdef __cplusplus } diff --git a/src/objective-c/tests/EnableCronet.m b/src/objective-c/tests/ConfigureCronet.m similarity index 86% rename from src/objective-c/tests/EnableCronet.m rename to src/objective-c/tests/ConfigureCronet.m index 5e0c933d835..ab137e28cad 100644 --- a/src/objective-c/tests/EnableCronet.m +++ b/src/objective-c/tests/ConfigureCronet.m @@ -18,13 +18,13 @@ #ifdef GRPC_COMPILE_WITH_CRONET -#import "EnableCronet.h" +#import "ConfigureCronet.h" #import -void enableCronet(void) { - static dispatch_once_t enableCronet; - dispatch_once(&enableCronet, ^{ - NSLog(@"enableCronet()"); +void configureCronet(void) { + static dispatch_once_t configureCronet; + dispatch_once(&configureCronet, ^{ + NSLog(@"configureCronet()"); [Cronet setHttp2Enabled:YES]; [Cronet setSslKeyLogFileName:@"Documents/key"]; [Cronet enableTestCertVerifierForTesting]; diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index 034d06b1976..a24734024dc 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -49,7 +49,7 @@ #import #include -#import "../EnableCronet.h" +#import "../ConfigureCronet.h" typedef struct fullstack_secure_fixture_data { char *localaddr; @@ -178,7 +178,7 @@ static char *roots_filename; grpc_init(); - enableCronet(); + configureCronet(); } // The tearDown() function is run after all test cases finish running diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index b0f3a3000f1..5ae0d77e37f 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -20,7 +20,7 @@ #import #import -#import "../EnableCronet.h" +#import "../ConfigureCronet.h" #import #import @@ -40,8 +40,8 @@ #import "test/core/util/test_config.h" #define GRPC_SHADOW_BORINGSSL_SYMBOLS -#import " #import "src/core/tsi/grpc_shadow_boringssl.h" +#import " static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; @@ -63,7 +63,7 @@ static void drain_cq(grpc_completion_queue *cq) { grpc_test_init(1, argv); grpc_init(); - enableCronet(); + configureCronet(); init_ssl(); } diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 89f5b96c38b..767c7c9c3c5 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -36,7 +36,7 @@ #import #import -#import "../EnableCronet.h" +#import "../ConfigureCronet.h" #import "InteropTestsBlockCallbacks.h" #define TEST_TIMEOUT 32 @@ -115,7 +115,7 @@ BOOL isRemoteInteropTest(NSString *host) { + (void)setUp { NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET - enableCronet(); + configureCronet(); if ([self useCronet]) { [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; } diff --git a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m index ffda48719e7..14ba2871aa2 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m +++ b/src/objective-c/tests/InteropTests/InteropTestsMultipleChannels.m @@ -26,7 +26,7 @@ #import #import -#import "../EnableCronet.h" +#import "../ConfigureCronet.h" #import "InteropTestsBlockCallbacks.h" #define NSStringize_helper(x) #x @@ -87,7 +87,7 @@ dispatch_once_t initCronet; _remoteService = [RMTTestService serviceWithHost:kRemoteSSLHost callOptions:nil]; - enableCronet(); + configureCronet(); // Default stack with remote host GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index c9d620ca2e9..60d2a98fba2 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -21,24 +21,20 @@ target 'MacTests' do pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true end -%w( - UnitTests -).each do |target_name| - target target_name do - platform :ios, '8.0' - pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true +target 'UnitTests' do + platform :ios, '8.0' + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true - pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'gRPC', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC - pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC - pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true - pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true - end + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC + pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true + pod 'RemoteTest', :path => "RemoteTestClient", :inhibit_warnings => true end %w( diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index c226e29d83b..737d52b547d 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -11,8 +11,8 @@ 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; 5E3F14862278BFFF007C6D90 /* InteropTestsBlockCallbacks.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */; }; - 5E3F148D22792856007C6D90 /* EnableCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* EnableCronet.m */; }; - 5E3F148E22792AF5007C6D90 /* EnableCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* EnableCronet.m */; }; + 5E3F148D22792856007C6D90 /* ConfigureCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */; }; + 5E3F148E22792AF5007C6D90 /* ConfigureCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */; }; 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; }; 5E7F486522775B41006656AD /* CronetUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.mm */; }; 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */; }; @@ -94,8 +94,8 @@ 5E0282E8215AA697007AC99D /* NSErrorUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSErrorUnitTests.m; sourceTree = ""; }; 5E3F14822278B42D007C6D90 /* InteropTestsBlockCallbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InteropTestsBlockCallbacks.h; sourceTree = ""; }; 5E3F14832278B461007C6D90 /* InteropTestsBlockCallbacks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsBlockCallbacks.m; sourceTree = ""; }; - 5E3F1487227918AA007C6D90 /* EnableCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EnableCronet.m; sourceTree = ""; }; - 5E3F148A227918C4007C6D90 /* EnableCronet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EnableCronet.h; sourceTree = ""; }; + 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ConfigureCronet.m; sourceTree = ""; }; + 5E3F148A227918C4007C6D90 /* ConfigureCronet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConfigureCronet.h; sourceTree = ""; }; 5E7F485922775B15006656AD /* CronetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CronetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E7F486622776AD8006656AD /* Cronet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cronet.framework; path = Pods/CronetFramework/Cronet.framework; sourceTree = ""; }; 5E7F486D22778086006656AD /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; @@ -396,8 +396,8 @@ 635697C91B14FC11007A7283 /* Tests */ = { isa = PBXGroup; children = ( - 5E3F148A227918C4007C6D90 /* EnableCronet.h */, - 5E3F1487227918AA007C6D90 /* EnableCronet.m */, + 5E3F148A227918C4007C6D90 /* ConfigureCronet.h */, + 5E3F1487227918AA007C6D90 /* ConfigureCronet.m */, 5EAFE8271F8EFB87007F2189 /* version.h */, 635697D71B14FC11007A7283 /* Supporting Files */, ); @@ -537,6 +537,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 635697BE1B14FC11007A7283; @@ -591,15 +592,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); @@ -613,15 +610,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cronet.framework", ); @@ -635,15 +628,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-CronetTests/Pods-CronetTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); @@ -679,15 +668,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-macOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); @@ -741,15 +726,11 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-InteropTests/Pods-InteropTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); @@ -819,7 +800,7 @@ buildActionMask = 2147483647; files = ( 5E3F14852278BF5D007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, - 5E3F148D22792856007C6D90 /* EnableCronet.m in Sources */, + 5E3F148D22792856007C6D90 /* ConfigureCronet.m in Sources */, 5E7F486E22778086006656AD /* CoreCronetEnd2EndTests.mm in Sources */, 5E7F488522778A88006656AD /* InteropTests.m in Sources */, 5E7F486422775B37006656AD /* InteropTestsRemoteWithCronet.m in Sources */, @@ -832,7 +813,7 @@ buildActionMask = 2147483647; files = ( 5E3F14842278B461007C6D90 /* InteropTestsBlockCallbacks.m in Sources */, - 5E3F148E22792AF5007C6D90 /* EnableCronet.m in Sources */, + 5E3F148E22792AF5007C6D90 /* ConfigureCronet.m in Sources */, 5E7F488922778B04006656AD /* InteropTestsRemote.m in Sources */, 5E7F487922778226006656AD /* InteropTestsMultipleChannels.m in Sources */, 5EA477042273617B000F72FC /* InteropTestsLocalCleartext.m in Sources */, diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme index a2b1614b991..adb3c366af2 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTests.xcscheme @@ -86,7 +86,7 @@ + buildConfiguration = "Cronet"> Date: Fri, 24 May 2019 10:58:14 -0700 Subject: [PATCH 131/676] Swap java interop tests to openjdk8 Since openjdk8 is dead to us (see #19113), we cannot leave openjdk8 in the list of runtimes in client_matrix.py. The list of runtimes is now the defaults to use, which includes master, and you can specify alternative runtimes per-release. Fixes #19113 --- .../Dockerfile.include | 6 +- .../grpc_interop_java/Dockerfile.template | 3 +- .../build_interop.sh.template | 2 +- .../grpc_interop_java/java_deps.include | 17 --- .../Dockerfile.template | 3 - .../build_interop.sh.template | 3 - .../java_deps.include | 12 --- .../interoptest/grpc_interop_java/Dockerfile | 18 +--- .../grpc_interop_java/build_interop.sh | 2 +- .../grpc_interop_java_oracle8/Dockerfile | 34 ------ .../build_interop.sh | 44 -------- tools/interop_matrix/README.md | 6 +- tools/interop_matrix/client_matrix.py | 100 +++++++++--------- 13 files changed, 64 insertions(+), 186 deletions(-) rename templates/tools/dockerfile/interoptest/{grpc_interop_java_oracle8 => grpc_interop_java}/Dockerfile.include (63%) delete mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_java/java_deps.include delete mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.template delete mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh.template delete mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include delete mode 100644 tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile delete mode 100644 tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include b/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.include similarity index 63% rename from templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include rename to templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.include index 7307e29f0a0..c0b2b745c14 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.include +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.include @@ -14,7 +14,11 @@ <%include file="../../debian_jessie_header.include"/> -<%include file="java_deps.include"/> +RUN echo "deb http://archive.debian.org/debian/ jessie-backports main contrib non-free" > /etc/apt/sources.list.d/jessie-backports.list && ${'\\'} + echo 'Acquire::Check-Valid-Until no;' > /etc/apt/apt.conf.d/99no-check-valid-until && ${'\\'} + apt-get update && ${'\\'} + apt-get install -y --no-install-recommends -t jessie-backports openjdk-8-jdk-headless && ${'\\'} + apt-get clean # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.template index 74d01809e22..8eaa9a9dbbc 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile.template @@ -1,4 +1,3 @@ %YAML 1.2 --- | - <%include file="../grpc_interop_java_oracle8/Dockerfile.include"/> - + <%include file="Dockerfile.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh.template index 42eb4d8b96e..db5d40d5488 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh.template @@ -1,3 +1,3 @@ %YAML 1.2 --- | - <%include file="../../java_build_interop.sh.include"/> + <%include file="../../java_build_interop.sh.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java/java_deps.include b/templates/tools/dockerfile/interoptest/grpc_interop_java/java_deps.include deleted file mode 100644 index 40d70e06d1a..00000000000 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java/java_deps.include +++ /dev/null @@ -1,17 +0,0 @@ -# Install JDK 8 and Git -# -RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && ${'\\'} - echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} - echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 - -RUN apt-get update && apt-get -y install ${'\\'} - git ${'\\'} - libapr1 ${'\\'} - oracle-java8-installer ${'\\'} - && ${'\\'} - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ - -ENV JAVA_HOME /usr/lib/jvm/java-8-oracle -ENV PATH $PATH:$JAVA_HOME/bin - diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.template deleted file mode 100644 index 8eaa9a9dbbc..00000000000 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile.template +++ /dev/null @@ -1,3 +0,0 @@ -%YAML 1.2 ---- | - <%include file="Dockerfile.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh.template deleted file mode 100644 index db5d40d5488..00000000000 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh.template +++ /dev/null @@ -1,3 +0,0 @@ -%YAML 1.2 ---- | - <%include file="../../java_build_interop.sh.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include b/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include deleted file mode 100644 index c05b5642393..00000000000 --- a/templates/tools/dockerfile/interoptest/grpc_interop_java_oracle8/java_deps.include +++ /dev/null @@ -1,12 +0,0 @@ -# Install JDK 8 -# -RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && ${'\\'} - echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} - echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && ${'\\'} - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && ${'\\'} - apt-get update && apt-get -y install oracle-java8-installer && ${'\\'} - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ - -ENV JAVA_HOME /usr/lib/jvm/java-8-oracle -ENV PATH $PATH:$JAVA_HOME/bin - diff --git a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile index 979c14db3f6..b7664b3c4c1 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_java/Dockerfile @@ -15,19 +15,11 @@ FROM debian:jessie -# Install JDK 8 -# -RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \ - echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \ - echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ - apt-get update && apt-get -y install oracle-java8-installer && \ - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ - -ENV JAVA_HOME /usr/lib/jvm/java-8-oracle -ENV PATH $PATH:$JAVA_HOME/bin - - +RUN echo "deb http://archive.debian.org/debian/ jessie-backports main contrib non-free" > /etc/apt/sources.list.d/jessie-backports.list && \ + echo 'Acquire::Check-Valid-Until no;' > /etc/apt/apt.conf.d/99no-check-valid-until && \ + apt-get update && \ + apt-get install -y --no-install-recommends -t jessie-backports openjdk-8-jdk-headless && \ + apt-get clean # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh index 8e1154679d7..77d322882f7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh @@ -41,4 +41,4 @@ java.util.logging.ConsoleHandler.level = ALL .level = FINE io.grpc.netty.NettyClientHandler = ALL io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt - + diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile deleted file mode 100644 index 979c14db3f6..00000000000 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM debian:jessie - - -# Install JDK 8 -# -RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \ - echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list && \ - echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886 && \ - apt-get update && apt-get -y install oracle-java8-installer && \ - apt-get clean && rm -r /var/cache/oracle-jdk8-installer/ - -ENV JAVA_HOME /usr/lib/jvm/java-8-oracle -ENV PATH $PATH:$JAVA_HOME/bin - - - -# Define the default command. -CMD ["bash"] - diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh deleted file mode 100644 index 77d322882f7..00000000000 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Copyright 2015 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Builds Java interop server and client in a base image. -set -e - -cp -r /var/local/jenkins/grpc-java /tmp/grpc-java - -# copy service account keys if available -cp -r /var/local/jenkins/service_account $HOME || true - -pushd /tmp/grpc-java -./gradlew :grpc-interop-testing:installDist -PskipCodegen=true - -mkdir -p /var/local/git/grpc-java/ -cp -r --parents -t /var/local/git/grpc-java/ \ - interop-testing/build/install/ \ - run-test-client.sh \ - run-test-server.sh - -popd -rm -r /tmp/grpc-java -rm -r "$HOME/.gradle" - -# enable extra java logging -mkdir -p /var/local/grpc_java_logging -echo "handlers = java.util.logging.ConsoleHandler -java.util.logging.ConsoleHandler.level = ALL -.level = FINE -io.grpc.netty.NettyClientHandler = ALL -io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt - diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 9d5c777cdee..2b37ee7d033 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -12,11 +12,11 @@ We have continuous nightly test setup to test gRPC backward compatibility betwee - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --upload_images --language cxx csharp python ruby php` - Verify that the new docker image was built successfully and uploaded to GCR. For example, - `gcloud container images list --repository gcr.io/grpc-testing` lists available images. - - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. + - `gcloud container images list-tags gcr.io/grpc-testing/grpc_interop_java` should show an image entry with tag `v1.9.9`. - images can also be viewed in https://pantheon.corp.google.com/gcr/images/grpc-testing?project=grpc-testing - Verify the just-created docker client image would pass backward compatibility test (it should). For example, - - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9` followed by - - `docker_image=gcr.io/grpc-testing/grpc_interop_java_oracle8:v1.9.9 tools/interop_matrix/testcases/java__master` + - `gcloud docker -- pull gcr.io/grpc-testing/grpc_interop_java:v1.9.9` followed by + - `docker_image=gcr.io/grpc-testing/grpc_interop_java:v1.9.9 tools/interop_matrix/testcases/java__master` - git commit the change and merge it to upstream/master. - (Optional) clean up the tmp directory to where grpc source is cloned at `/export/hda3/tmp/grpc_matrix/`. For more details on each step, refer to sections below. diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index f9c069f6389..56fbbcab033 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -37,12 +37,8 @@ def get_runtimes_for_lang_release(lang, release): """Get list of valid runtimes for given release of lang.""" runtimes = list(LANG_RUNTIME_MATRIX[lang]) release_info = LANG_RELEASE_MATRIX[lang].get(release) - if release_info and release_info.runtime_subset: - runtimes = list(release_info.runtime_subset) - - # check that all selected runtimes are valid for given language - for runtime in runtimes: - assert runtime in LANG_RUNTIME_MATRIX[lang] + if release_info and release_info.runtimes: + runtimes = list(release_info.runtimes) return runtimes @@ -55,11 +51,11 @@ def should_build_docker_interop_image_from_release_tag(lang): return True -# Dictionary of runtimes per language +# Dictionary of default runtimes per language LANG_RUNTIME_MATRIX = { 'cxx': ['cxx'], # This is actually debian8. 'go': ['go1.8', 'go1.11'], - 'java': ['java_oracle8'], + 'java': ['java'], 'python': ['python'], 'node': ['node'], 'ruby': ['ruby'], @@ -71,9 +67,9 @@ LANG_RUNTIME_MATRIX = { class ReleaseInfo: """Info about a single release of a language""" - def __init__(self, patch=[], runtime_subset=[], testcases_file=None): + def __init__(self, patch=[], runtimes=[], testcases_file=None): self.patch = patch - self.runtime_subset = runtime_subset + self.runtimes = runtimes self.testcases_file = testcases_file @@ -104,51 +100,51 @@ LANG_RELEASE_MATRIX = { ]), 'go': OrderedDict([ - ('v1.0.5', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.2.1', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.3.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.4.2', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.5.2', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.6.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.7.4', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.8.2', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.9.2', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.10.1', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.11.3', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.12.2', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.13.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.14.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), - ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), - ('v1.18.0', ReleaseInfo(runtime_subset=['go1.11'])), - ('v1.19.0', ReleaseInfo(runtime_subset=['go1.11'])), - ('v1.20.0', ReleaseInfo(runtime_subset=['go1.11'])), - ('v1.21.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.0.5', ReleaseInfo(runtimes=['go1.8'])), + ('v1.2.1', ReleaseInfo(runtimes=['go1.8'])), + ('v1.3.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.4.2', ReleaseInfo(runtimes=['go1.8'])), + ('v1.5.2', ReleaseInfo(runtimes=['go1.8'])), + ('v1.6.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.7.4', ReleaseInfo(runtimes=['go1.8'])), + ('v1.8.2', ReleaseInfo(runtimes=['go1.8'])), + ('v1.9.2', ReleaseInfo(runtimes=['go1.8'])), + ('v1.10.1', ReleaseInfo(runtimes=['go1.8'])), + ('v1.11.3', ReleaseInfo(runtimes=['go1.8'])), + ('v1.12.2', ReleaseInfo(runtimes=['go1.8'])), + ('v1.13.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.14.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.15.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.16.0', ReleaseInfo(runtimes=['go1.8'])), + ('v1.17.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.18.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.19.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.20.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.21.0', ReleaseInfo(runtimes=['go1.11'])), ]), 'java': OrderedDict([ - ('v1.0.3', ReleaseInfo()), - ('v1.1.2', ReleaseInfo()), - ('v1.2.0', ReleaseInfo()), - ('v1.3.1', ReleaseInfo()), - ('v1.4.0', ReleaseInfo()), - ('v1.5.0', ReleaseInfo()), - ('v1.6.1', ReleaseInfo()), - ('v1.7.0', ReleaseInfo()), - ('v1.8.0', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.0', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.1', ReleaseInfo()), - ('v1.14.0', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.1', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), - ('v1.18.0', ReleaseInfo()), - ('v1.19.0', ReleaseInfo()), - ('v1.20.0', ReleaseInfo()), + ('v1.0.3', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.1.2', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.2.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.3.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.4.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.5.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.6.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.7.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.8.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.9.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.10.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.11.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.12.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.13.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.14.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.15.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.16.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.17.1', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.18.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.19.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.20.0', ReleaseInfo(runtimes=['java_oracle8'])), ]), 'python': OrderedDict([ From 155ca4be68571ea56f3dee85c11196c8c44e39b5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 May 2019 12:37:33 -0700 Subject: [PATCH 132/676] Polish scheme configurations --- .../xcshareddata/xcschemes/CronetTests.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme index ac8cfc971c8..0156c906971 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CronetTests.xcscheme @@ -70,7 +70,7 @@ + buildConfiguration = "Cronet"> Date: Fri, 24 May 2019 12:51:14 -0700 Subject: [PATCH 133/676] clang-format --- src/objective-c/tests/CronetTests/CronetUnitTests.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 5ae0d77e37f..595a1d19708 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -40,8 +40,8 @@ #import "test/core/util/test_config.h" #define GRPC_SHADOW_BORINGSSL_SYMBOLS -#import "src/core/tsi/grpc_shadow_boringssl.h" #import " +#import "src/core/tsi/grpc_shadow_boringssl.h" static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; From 886dc10daa669d96c7e9722a736efee60d5eaee3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 May 2019 14:29:16 -0700 Subject: [PATCH 134/676] Move validate_service_config to a new file --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 6 +++ Makefile | 6 +++ build.yaml | 2 + gRPC-C++.podspec | 2 + grpc.gyp | 2 + .../grpcpp/support/channel_arguments_impl.h | 9 ----- .../grpcpp/support/validate_service_config.h | 36 +++++++++++++++++ src/cpp/common/channel_arguments.cc | 18 --------- src/cpp/common/validate_service_config.cc | 40 +++++++++++++++++++ .../end2end/service_config_end2end_test.cc | 1 + tools/doxygen/Doxyfile.c++ | 3 +- tools/doxygen/Doxyfile.c++.internal | 2 + .../generated/sources_and_headers.json | 3 ++ 15 files changed, 106 insertions(+), 28 deletions(-) create mode 100644 include/grpcpp/support/validate_service_config.h create mode 100644 src/cpp/common/validate_service_config.cc diff --git a/BUILD b/BUILD index ddd1f97b541..edfc19a6080 100644 --- a/BUILD +++ b/BUILD @@ -137,6 +137,7 @@ GRPCXX_SRCS = [ "src/cpp/common/resource_quota_cc.cc", "src/cpp/common/rpc_method.cc", "src/cpp/common/version_cc.cc", + "src/cpp/common/validate_service_config.cc", "src/cpp/server/async_generic_service.cc", "src/cpp/server/channel_argument_option.cc", "src/cpp/server/create_default_thread_pool.cc", @@ -284,6 +285,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", "include/grpcpp/support/time.h", + "include/grpcpp/support/validate_service_config.h", ] grpc_cc_library( diff --git a/BUILD.gn b/BUILD.gn index dcd5bc880eb..8e493af7540 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1141,6 +1141,7 @@ config("grpc_config") { "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", "include/grpcpp/support/time.h", + "include/grpcpp/support/validate_service_config.h", "src/core/ext/transport/inproc/inproc_transport.h", "src/core/lib/avl/avl.h", "src/core/lib/backoff/backoff.h", @@ -1340,6 +1341,7 @@ config("grpc_config") { "src/cpp/common/secure_auth_context.h", "src/cpp/common/secure_channel_arguments.cc", "src/cpp/common/secure_create_auth_context.cc", + "src/cpp/common/validate_service_config.cc", "src/cpp/common/version_cc.cc", "src/cpp/server/async_generic_service.cc", "src/cpp/server/channel_argument_option.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 429d083d279..c2da881909d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2977,6 +2977,7 @@ add_library(grpc++ src/cpp/common/core_codegen.cc src/cpp/common/resource_quota_cc.cc src/cpp/common/rpc_method.cc + src/cpp/common/validate_service_config.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc src/cpp/server/channel_argument_option.cc @@ -3151,6 +3152,7 @@ foreach(_hdr include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h include/grpcpp/support/time.h + include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h @@ -3373,6 +3375,7 @@ add_library(grpc++_cronet src/cpp/common/core_codegen.cc src/cpp/common/resource_quota_cc.cc src/cpp/common/rpc_method.cc + src/cpp/common/validate_service_config.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc src/cpp/server/channel_argument_option.cc @@ -3767,6 +3770,7 @@ foreach(_hdr include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h include/grpcpp/support/time.h + include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h @@ -4584,6 +4588,7 @@ add_library(grpc++_unsecure src/cpp/common/core_codegen.cc src/cpp/common/resource_quota_cc.cc src/cpp/common/rpc_method.cc + src/cpp/common/validate_service_config.cc src/cpp/common/version_cc.cc src/cpp/server/async_generic_service.cc src/cpp/server/channel_argument_option.cc @@ -4757,6 +4762,7 @@ foreach(_hdr include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h include/grpcpp/support/time.h + include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h diff --git a/Makefile b/Makefile index 605e533e8a8..a462b5c5074 100644 --- a/Makefile +++ b/Makefile @@ -5370,6 +5370,7 @@ LIBGRPC++_SRC = \ src/cpp/common/core_codegen.cc \ src/cpp/common/resource_quota_cc.cc \ src/cpp/common/rpc_method.cc \ + src/cpp/common/validate_service_config.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ src/cpp/server/channel_argument_option.cc \ @@ -5509,6 +5510,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ + include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ include/grpc/support/atm.h \ include/grpc/support/atm_gcc_atomic.h \ @@ -5775,6 +5777,7 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/common/core_codegen.cc \ src/cpp/common/resource_quota_cc.cc \ src/cpp/common/rpc_method.cc \ + src/cpp/common/validate_service_config.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ src/cpp/server/channel_argument_option.cc \ @@ -6133,6 +6136,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ + include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ include/grpc/support/atm.h \ include/grpc/support/atm_gcc_atomic.h \ @@ -6933,6 +6937,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/common/core_codegen.cc \ src/cpp/common/resource_quota_cc.cc \ src/cpp/common/rpc_method.cc \ + src/cpp/common/validate_service_config.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ src/cpp/server/channel_argument_option.cc \ @@ -7072,6 +7077,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ + include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ include/grpc/support/atm.h \ include/grpc/support/atm_gcc_atomic.h \ diff --git a/build.yaml b/build.yaml index e2a1b75dda5..99820507a6f 100644 --- a/build.yaml +++ b/build.yaml @@ -1428,6 +1428,7 @@ filegroups: - include/grpcpp/support/stub_options.h - include/grpcpp/support/sync_stream.h - include/grpcpp/support/time.h + - include/grpcpp/support/validate_service_config.h headers: - src/cpp/client/create_channel_internal.h - src/cpp/common/channel_filter.h @@ -1451,6 +1452,7 @@ filegroups: - src/cpp/common/core_codegen.cc - src/cpp/common/resource_quota_cc.cc - src/cpp/common/rpc_method.cc + - src/cpp/common/validate_service_config.cc - src/cpp/common/version_cc.cc - src/cpp/server/async_generic_service.cc - src/cpp/server/channel_argument_option.cc diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 10e37bb5f47..17a87304aae 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -148,6 +148,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/stub_options.h', 'include/grpcpp/support/sync_stream.h', 'include/grpcpp/support/time.h', + 'include/grpcpp/support/validate_service_config.h', 'include/grpcpp/impl/codegen/async_generic_service.h', 'include/grpcpp/impl/codegen/async_stream.h', 'include/grpcpp/impl/codegen/async_unary_call.h', @@ -233,6 +234,7 @@ Pod::Spec.new do |s| 'src/cpp/common/core_codegen.cc', 'src/cpp/common/resource_quota_cc.cc', 'src/cpp/common/rpc_method.cc', + 'src/cpp/common/validate_service_config.cc', 'src/cpp/common/version_cc.cc', 'src/cpp/server/async_generic_service.cc', 'src/cpp/server/channel_argument_option.cc', diff --git a/grpc.gyp b/grpc.gyp index 833a0b48715..1668900a3c7 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1447,6 +1447,7 @@ 'src/cpp/common/core_codegen.cc', 'src/cpp/common/resource_quota_cc.cc', 'src/cpp/common/rpc_method.cc', + 'src/cpp/common/validate_service_config.cc', 'src/cpp/common/version_cc.cc', 'src/cpp/server/async_generic_service.cc', 'src/cpp/server/channel_argument_option.cc', @@ -1602,6 +1603,7 @@ 'src/cpp/common/core_codegen.cc', 'src/cpp/common/resource_quota_cc.cc', 'src/cpp/common/rpc_method.cc', + 'src/cpp/common/validate_service_config.cc', 'src/cpp/common/version_cc.cc', 'src/cpp/server/async_generic_service.cc', 'src/cpp/server/channel_argument_option.cc', diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index a137a5b7c7d..0efeadca880 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -31,15 +31,6 @@ namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing - -namespace experimental { -/// Validates \a service_config_json. If valid, returns an empty string. -/// Otherwise, returns the validation error. -/// TODO(yashykt): Promote it to out of experimental once it is proved useful -/// and gRFC is accepted. -grpc::string ValidateServiceConfigJSON(const grpc::string& service_config_json); -} // namespace experimental - } // namespace grpc namespace grpc_impl { diff --git a/include/grpcpp/support/validate_service_config.h b/include/grpcpp/support/validate_service_config.h new file mode 100644 index 00000000000..d5ea521a1ef --- /dev/null +++ b/include/grpcpp/support/validate_service_config.h @@ -0,0 +1,36 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_VALIDATE_SERVICE_CONFIG_H +#define GRPCPP_SUPPORT_VALIDATE_SERVICE_CONFIG_H + +#include + +namespace grpc { + +namespace experimental { +/// Validates \a service_config_json. If valid, returns an empty string. +/// Otherwise, returns the validation error. +/// TODO(yashykt): Promote it to out of experimental once it is proved useful +/// and gRFC is accepted. +grpc::string ValidateServiceConfigJSON(const grpc::string& service_config_json); +} // namespace experimental + +} // namespace grpc + +#endif // GRPCPP_SUPPORT_VALIDATE_SERVICE_CONFIG_H \ No newline at end of file diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index b97e1ed8da9..f35c91572eb 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -217,21 +217,3 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } // namespace grpc_impl - -namespace grpc { -namespace experimental { -grpc::string ValidateServiceConfigJSON( - const grpc::string& service_config_json) { - grpc_init(); - grpc_error* error = GRPC_ERROR_NONE; - grpc_core::ServiceConfig::Create(service_config_json.c_str(), &error); - grpc::string return_value; - if (error != GRPC_ERROR_NONE) { - return_value = grpc_error_string(error); - GRPC_ERROR_UNREF(error); - } - grpc_shutdown(); - return return_value; -} -} // namespace experimental -} // namespace grpc diff --git a/src/cpp/common/validate_service_config.cc b/src/cpp/common/validate_service_config.cc new file mode 100644 index 00000000000..0f193cf1c42 --- /dev/null +++ b/src/cpp/common/validate_service_config.cc @@ -0,0 +1,40 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "src/core/ext/filters/client_channel/service_config.h" + +namespace grpc { +namespace experimental { +grpc::string ValidateServiceConfigJSON( + const grpc::string& service_config_json) { + grpc_init(); + grpc_error* error = GRPC_ERROR_NONE; + grpc_core::ServiceConfig::Create(service_config_json.c_str(), &error); + grpc::string return_value; + if (error != GRPC_ERROR_NONE) { + return_value = grpc_error_string(error); + GRPC_ERROR_UNREF(error); + } + grpc_shutdown(); + return return_value; +} +} // namespace experimental +} // namespace grpc diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index e5c3a8e3eff..14786b98f85 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 667b9b3541e..913d7be993b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1040,7 +1040,8 @@ include/grpcpp/support/status_code_enum.h \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ -include/grpcpp/support/time.h +include/grpcpp/support/time.h \ +include/grpcpp/support/validate_service_config.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 529b35a2c39..58192bfc34b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1043,6 +1043,7 @@ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ +include/grpcpp/support/validate_service_config.h \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/transport/inproc/inproc_transport.h \ @@ -1245,6 +1246,7 @@ src/cpp/common/secure_auth_context.cc \ src/cpp/common/secure_auth_context.h \ src/cpp/common/secure_channel_arguments.cc \ src/cpp/common/secure_create_auth_context.cc \ +src/cpp/common/validate_service_config.cc \ src/cpp/common/version_cc.cc \ src/cpp/server/async_generic_service.cc \ src/cpp/server/channel_argument_option.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index e67465d1602..677fff1d48b 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10311,6 +10311,7 @@ "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", "include/grpcpp/support/time.h", + "include/grpcpp/support/validate_service_config.h", "src/cpp/client/create_channel_internal.h", "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", @@ -10436,6 +10437,7 @@ "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", "include/grpcpp/support/time.h", + "include/grpcpp/support/validate_service_config.h", "src/cpp/client/channel_cc.cc", "src/cpp/client/client_context.cc", "src/cpp/client/client_interceptor.cc", @@ -10453,6 +10455,7 @@ "src/cpp/common/core_codegen.cc", "src/cpp/common/resource_quota_cc.cc", "src/cpp/common/rpc_method.cc", + "src/cpp/common/validate_service_config.cc", "src/cpp/common/version_cc.cc", "src/cpp/server/async_generic_service.cc", "src/cpp/server/channel_argument_option.cc", From 384f15ab6eb68610d04b1149e1341564f428e2e4 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 24 May 2019 14:46:12 -0700 Subject: [PATCH 135/676] Delay calling plugin_creds callback --- .../credentials/plugin/plugin_credentials.cc | 62 +++++-------- .../credentials/plugin/plugin_credentials.h | 7 +- .../security/transport/client_auth_filter.cc | 2 - test/cpp/end2end/end2end_test.cc | 88 +++++++++++++++---- 4 files changed, 94 insertions(+), 65 deletions(-) diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 333366d0f0a..8e926de59da 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -54,15 +54,10 @@ void grpc_plugin_credentials::pending_request_remove_locked( } } -// Checks if the request has been cancelled. -// If not, removes it from the pending list, so that it cannot be -// cancelled out from under us. -// When this returns, r->cancelled indicates whether the request was -// cancelled before completion. void grpc_plugin_credentials::pending_request_complete(pending_request* r) { GPR_DEBUG_ASSERT(r->creds == this); gpr_mu_lock(&mu_); - if (!r->cancelled) pending_request_remove_locked(r); + pending_request_remove_locked(r); gpr_mu_unlock(&mu_); // Ref to credentials not needed anymore. Unref(); @@ -76,7 +71,8 @@ static grpc_error* process_plugin_result( char* msg; gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s", error_details); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg), + GRPC_ERROR_INT_GRPC_STATUS, status); gpr_free(msg); } else { bool seen_illegal_header = false; @@ -95,7 +91,9 @@ static grpc_error* process_plugin_result( } } if (seen_illegal_header) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata"); + error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata."), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL); } else { for (size_t i = 0; i < num_md; ++i) { grpc_mdelem mdelem = @@ -125,19 +123,18 @@ static void plugin_md_request_metadata_ready(void* request, "asynchronously", r->creds, r); } - // Remove request from pending list if not previously cancelled. + // Remove request from pending list r->creds->pending_request_complete(r); // If it has not been cancelled, process it. - if (!r->cancelled) { - grpc_error* error = - process_plugin_result(r, md, num_md, status, error_details); - GRPC_CLOSURE_SCHED(r->on_request_metadata, error); + if (r->error == GRPC_ERROR_NONE) { + r->error = process_plugin_result(r, md, num_md, status, error_details); } else if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin was previously " "cancelled", r->creds, r); } + GRPC_CLOSURE_SCHED(r->on_request_metadata, r->error); gpr_free(r); } @@ -145,11 +142,11 @@ bool grpc_plugin_credentials::get_request_metadata( grpc_polling_entity* pollent, grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, grpc_error** error) { - bool retval = true; // Synchronous return. if (plugin_.get_metadata != nullptr) { // Create pending_request object. pending_request* request = static_cast(gpr_zalloc(sizeof(*request))); + request->error = GRPC_ERROR_NONE; request->creds = this; request->md_array = md_array; request->on_request_metadata = on_request_metadata; @@ -183,29 +180,16 @@ bool grpc_plugin_credentials::get_request_metadata( return false; // Asynchronous return. } // Returned synchronously. - // Remove request from pending list if not previously cancelled. + // Remove request from pending list. request->creds->pending_request_complete(request); - // If the request was cancelled, the error will have been returned - // asynchronously by plugin_cancel_get_request_metadata(), so return - // false. Otherwise, process the result. - if (request->cancelled) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { - gpr_log(GPR_INFO, - "plugin_credentials[%p]: request %p was cancelled, error " - "will be returned asynchronously", - this, request); - } - retval = false; - } else { - if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { - gpr_log(GPR_INFO, - "plugin_credentials[%p]: request %p: plugin returned " - "synchronously", - this, request); - } - *error = process_plugin_result(request, creds_md, num_creds_md, status, - error_details); + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { + gpr_log(GPR_INFO, + "plugin_credentials[%p]: request %p: plugin returned " + "synchronously", + this, request); } + *error = process_plugin_result(request, creds_md, num_creds_md, status, + error_details); // Clean up. for (size_t i = 0; i < num_creds_md; ++i) { grpc_slice_unref_internal(creds_md[i].key); @@ -214,7 +198,7 @@ bool grpc_plugin_credentials::get_request_metadata( gpr_free((void*)error_details); gpr_free(request); } - return retval; + return true; // Synchronous return. } void grpc_plugin_credentials::cancel_get_request_metadata( @@ -227,15 +211,11 @@ void grpc_plugin_credentials::cancel_get_request_metadata( gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } - pending_request->cancelled = true; - GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, - GRPC_ERROR_REF(error)); - pending_request_remove_locked(pending_request); + pending_request->error = error; break; } } gpr_mu_unlock(&mu_); - GRPC_ERROR_UNREF(error); } grpc_plugin_credentials::grpc_plugin_credentials( diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h index 77a957e5137..7350b37f8a5 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.h +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h @@ -31,7 +31,7 @@ extern grpc_core::TraceFlag grpc_plugin_credentials_trace; struct grpc_plugin_credentials final : public grpc_call_credentials { public: struct pending_request { - bool cancelled; + grpc_error* error; struct grpc_plugin_credentials* creds; grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; @@ -51,11 +51,6 @@ struct grpc_plugin_credentials final : public grpc_call_credentials { void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, grpc_error* error) override; - // Checks if the request has been cancelled. - // If not, removes it from the pending list, so that it cannot be - // cancelled out from under us. - // When this returns, r->cancelled indicates whether the request was - // cancelled before completion. void pending_request_complete(pending_request* r); private: diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 0c40dd7ff1e..40393de2b13 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -160,8 +160,6 @@ static void on_credentials_metadata(void* arg, grpc_error* input_error) { if (error == GRPC_ERROR_NONE) { grpc_call_next_op(elem, batch); } else { - error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, - GRPC_STATUS_UNAVAILABLE); grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index c027e5954ec..a505d1a633f 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -90,11 +90,13 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { TestMetadataCredentialsPlugin(const grpc::string_ref& metadata_key, const grpc::string_ref& metadata_value, - bool is_blocking, bool is_successful) + bool is_blocking, bool is_successful, + int delay_ms) : metadata_key_(metadata_key.data(), metadata_key.length()), metadata_value_(metadata_value.data(), metadata_value.length()), is_blocking_(is_blocking), - is_successful_(is_successful) {} + is_successful_(is_successful), + delay_ms_(delay_ms) {} bool IsBlocking() const override { return is_blocking_; } @@ -102,6 +104,11 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { grpc::string_ref service_url, grpc::string_ref method_name, const grpc::AuthContext& channel_auth_context, std::multimap* metadata) override { + if (delay_ms_ != 0) { + gpr_sleep_until( + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(delay_ms_, GPR_TIMESPAN))); + } EXPECT_GT(service_url.length(), 0UL); EXPECT_GT(method_name.length(), 0UL); EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated()); @@ -119,6 +126,7 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { grpc::string metadata_value_; bool is_blocking_; bool is_successful_; + int delay_ms_; }; const char TestMetadataCredentialsPlugin::kBadMetadataKey[] = @@ -137,7 +145,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, - is_blocking_, true))); + is_blocking_, true, 0))); } std::shared_ptr GetIncompatibleClientCreds() { @@ -145,7 +153,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", - is_blocking_, true))); + is_blocking_, true, 0))); } // Interface implementation @@ -1835,12 +1843,13 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, - "Does not matter, will fail the key is invalid.", false, true)))); + "Does not matter, will fail the key is invalid.", false, true, + 0)))); request.set_message("Hello"); Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(s.error_code(), StatusCode::INTERNAL); } TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { @@ -1853,12 +1862,59 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, - "With illegal \n value.", false, true)))); + "With illegal \n value.", false, true, 0)))); request.set_message("Hello"); Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(s.error_code(), StatusCode::INTERNAL); +} + +TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { + MAYBE_SKIP_TEST; + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + const int delay = 100; + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::milliseconds(delay); + context.set_deadline(deadline); + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin("meta_key", "Does not matter", true, + true, delay)))); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + if (!s.ok()) { + EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code()); + } +} + +TEST_P(SecureEnd2endTest, AuthMetadataPluginWithCancel) { + MAYBE_SKIP_TEST; + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + const int delay = 100; + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin("meta_key", "Does not matter", true, + true, delay)))); + request.set_message("Hello"); + + std::thread cancel_thread([&context] { + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(delay, GPR_TIMESPAN))); + context.TryCancel(); + }); + Status s = stub_->Echo(&context, request, &response); + if (!s.ok()) { + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + } + cancel_thread.join(); } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { @@ -1871,13 +1927,13 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, - "Does not matter, will fail anyway (see 3rd param)", false, - false)))); + "Does not matter, will fail anyway (see 3rd param)", false, false, + 0)))); request.set_message("Hello"); Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(s.error_code(), StatusCode::NOT_FOUND); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); @@ -1935,13 +1991,13 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, - "Does not matter, will fail anyway (see 3rd param)", true, - false)))); + "Does not matter, will fail anyway (see 3rd param)", true, false, + 0)))); request.set_message("Hello"); Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(s.error_code(), StatusCode::NOT_FOUND); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); @@ -1962,11 +2018,11 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, - true, true))), + true, true, 0))), grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, - true, true))))); + true, true, 0))))); request.set_message("Hello"); request.mutable_param()->set_echo_metadata(true); From b1147052d362e13ee25418d0ee079b2d7ec626c3 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 24 May 2019 14:10:11 -0700 Subject: [PATCH 136/676] cfstream_test: print HTTP2 stream id of completed RPCs Log stream id of completed RPCs. This helps in debugging test failures. --- test/cpp/end2end/cfstream_test.cc | 37 ++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index 59cf98ffc20..b0c55616de3 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -42,6 +42,7 @@ #include "src/core/lib/gpr/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/debugger_macros.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" @@ -144,6 +145,18 @@ class CFStreamTest : public ::testing::TestWithParam { return CreateCustomChannel(server_address.str(), channel_creds, args); } + int GetStreamID(ClientContext& context) { + int stream_id = 0; + grpc_call* call = context.c_call(); + if (call) { + grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); + if (stream) { + stream_id = stream->id; + } + } + return stream_id; + } + void SendRpc( const std::unique_ptr& stub, bool expect_success = false) { @@ -153,10 +166,13 @@ class CFStreamTest : public ::testing::TestWithParam { request.set_message(msg); ClientContext context; Status status = stub->Echo(&context, request, response.get()); + int stream_id = GetStreamID(context); if (status.ok()) { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); EXPECT_EQ(msg, response->message()); } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, + status.error_message().c_str()); } if (expect_success) { EXPECT_TRUE(status.ok()); @@ -359,14 +375,17 @@ TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { ++total_completions; GPR_ASSERT(ok); AsyncClientCall* call = static_cast(got_tag); + int stream_id = GetStreamID(call->context); if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC failed with error: %s", - call->status.error_message().c_str()); + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", + stream_id, call->status.error_message().c_str()); // Bring network up when RPCs start failing if (network_down) { NetworkUp(); network_down = false; } + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); } delete call; } @@ -393,21 +412,19 @@ TEST_P(CFStreamTest, ConcurrentRpc) { std::thread thd = std::thread([this, &rpcs_sent]() { void* got_tag; bool ok = false; - bool network_down = true; int total_completions = 0; while (CQNext(&got_tag, &ok)) { ++total_completions; GPR_ASSERT(ok); AsyncClientCall* call = static_cast(got_tag); + int stream_id = GetStreamID(call->context); if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC failed: %s", - call->status.error_message().c_str()); + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", + stream_id, call->status.error_message().c_str()); // Bring network up when RPCs start failing - if (network_down) { - NetworkUp(); - network_down = false; - } + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); } delete call; } From 67bdbbdf6f6592d63d6b0749f1e73a5c846b59fa Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 May 2019 16:58:56 -0700 Subject: [PATCH 137/676] Fix a bug where POST_RECV_MESSAGE is not being triggered --- include/grpcpp/impl/codegen/call_op_set.h | 7 +- .../client_interceptors_end2end_test.cc | 74 ++++++++++++++++++- test/cpp/end2end/interceptors_util.cc | 6 +- test/cpp/end2end/interceptors_util.h | 2 + 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index d810625b3e4..fdd0b5e91b7 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -433,7 +433,9 @@ class CallOpRecvMessage { message_(nullptr), allow_not_getting_message_(false) {} - void RecvMessage(R* message) { message_ = message; } + void RecvMessage(R* message) { + message_ = message; + } // Do not change status if no message is received. void AllowNoMessage() { allow_not_getting_message_ = true; } @@ -468,7 +470,6 @@ class CallOpRecvMessage { *status = false; } } - message_ = nullptr; } void SetInterceptionHookPoint( @@ -565,7 +566,6 @@ class CallOpGenericRecvMessage { *status = false; } } - deserialize_.reset(); } void SetInterceptionHookPoint( @@ -580,6 +580,7 @@ class CallOpGenericRecvMessage { interceptor_methods->AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE); if (!got_message) interceptor_methods->SetRecvMessage(nullptr, nullptr); + deserialize_.reset(); } void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) { hijacked_ = true; diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index f1aed093dc4..70b0ecdf585 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -501,7 +501,14 @@ class BidiStreamingRpcHijackingInterceptorFactory class LoggingInterceptor : public experimental::Interceptor { public: - LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } + LoggingInterceptor(experimental::ClientRpcInfo* info) : info_(info) { + pre_send_initial_metadata_ = false; + pre_send_message_count_ = 0; + pre_send_close_ = false; + post_recv_initial_metadata_ = false; + post_recv_message_count_ = 0; + post_recv_status_ = false; + } virtual void Intercept(experimental::InterceptorBatchMethods* methods) { if (methods->QueryInterceptionHookPoint( @@ -512,6 +519,8 @@ class LoggingInterceptor : public experimental::Interceptor { auto iterator = map->begin(); EXPECT_EQ("testkey", iterator->first); EXPECT_EQ("testvalue", iterator->second); + ASSERT_FALSE(pre_send_initial_metadata_); + pre_send_initial_metadata_ = true; } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { @@ -526,22 +535,28 @@ class LoggingInterceptor : public experimental::Interceptor { SerializationTraits::Deserialize(&copied_buffer, &req) .ok()); EXPECT_TRUE(req.message().find("Hello") == 0u); + pre_send_message_count_++; } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { // Got nothing to do here for now + pre_send_close_ = true; } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) { auto* map = methods->GetRecvInitialMetadata(); // Got nothing better to do here for now EXPECT_EQ(map->size(), static_cast(0)); + post_recv_initial_metadata_ = true; } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0u); + if(resp != nullptr) { + EXPECT_TRUE(resp->message().find("Hello") == 0u); + post_recv_message_count_++; + } } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_STATUS)) { @@ -556,14 +571,59 @@ class LoggingInterceptor : public experimental::Interceptor { EXPECT_EQ(found, true); auto* status = methods->GetRecvStatus(); EXPECT_EQ(status->ok(), true); + post_recv_status_ = true; } methods->Proceed(); } + static void VerifyCallCommon() { + EXPECT_TRUE(pre_send_initial_metadata_); + EXPECT_TRUE(pre_send_close_); + EXPECT_TRUE(post_recv_initial_metadata_); + EXPECT_TRUE(post_recv_status_); + } + + static void VerifyUnaryCall() { + VerifyCallCommon(); + EXPECT_EQ(pre_send_message_count_, 1); + EXPECT_EQ(post_recv_message_count_, 1); + } + + static void VerifyClientStreamingCall() { + VerifyCallCommon(); + EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); + EXPECT_EQ(post_recv_message_count_, 1); + } + + static void VerifyServerStreamingCall() { + VerifyCallCommon(); + EXPECT_EQ(pre_send_message_count_, 1); + EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); + } + + static void VerifyBidiStreamingCall() { + VerifyCallCommon(); + EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); + EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); + } + private: experimental::ClientRpcInfo* info_; + static bool pre_send_initial_metadata_; + static int pre_send_message_count_; + static bool pre_send_close_; + static bool post_recv_initial_metadata_; + static int post_recv_message_count_; + static bool post_recv_status_; }; +bool LoggingInterceptor::pre_send_initial_metadata_; +int LoggingInterceptor::pre_send_message_count_; +bool LoggingInterceptor::pre_send_close_; +bool LoggingInterceptor::post_recv_initial_metadata_; +int LoggingInterceptor::post_recv_message_count_; +bool LoggingInterceptor::post_recv_status_; + class LoggingInterceptorFactory : public experimental::ClientInterceptorFactoryInterface { public: @@ -607,6 +667,7 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeCall(channel); + LoggingInterceptor::VerifyUnaryCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -643,7 +704,6 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) { } auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); // Make sure only 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -659,8 +719,8 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) { new HijackingInterceptorFactory())); auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); - MakeCall(channel); + LoggingInterceptor::VerifyUnaryCall(); } TEST_F(ClientInterceptorsEnd2endTest, @@ -708,6 +768,7 @@ TEST_F(ClientInterceptorsEnd2endTest, auto channel = server_->experimental().InProcessChannelWithInterceptors( args, std::move(creators)); MakeCallbackCall(channel); + LoggingInterceptor::VerifyUnaryCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -730,6 +791,7 @@ TEST_F(ClientInterceptorsEnd2endTest, auto channel = server_->experimental().InProcessChannelWithInterceptors( args, std::move(creators)); MakeCallbackCall(channel); + LoggingInterceptor::VerifyUnaryCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -768,6 +830,7 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeClientStreamingCall(channel); + LoggingInterceptor::VerifyClientStreamingCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -787,6 +850,7 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeServerStreamingCall(channel); + LoggingInterceptor::VerifyServerStreamingCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -862,6 +926,7 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeBidiStreamingCall(channel); + LoggingInterceptor::VerifyBidiStreamingCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); } @@ -928,6 +993,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { auto channel = experimental::CreateCustomChannelWithInterceptors( server_address_, InsecureChannelCredentials(), args, std::move(creators)); MakeCall(channel); + LoggingInterceptor::VerifyUnaryCall(); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); experimental::TestOnlyResetGlobalClientInterceptorFactory(); diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc index 900f02b5f36..6321c35ba4a 100644 --- a/test/cpp/end2end/interceptors_util.cc +++ b/test/cpp/end2end/interceptors_util.cc @@ -48,7 +48,7 @@ void MakeClientStreamingCall(const std::shared_ptr& channel) { EchoResponse resp; string expected_resp = ""; auto writer = stub->RequestStream(&ctx, &resp); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < kNumStreamingMessages; i++) { writer->Write(req); expected_resp += "Hello"; } @@ -73,7 +73,7 @@ void MakeServerStreamingCall(const std::shared_ptr& channel) { EXPECT_EQ(resp.message(), "Hello"); count++; } - ASSERT_EQ(count, 10); + ASSERT_EQ(count, kNumStreamingMessages); Status s = reader->Finish(); EXPECT_EQ(s.ok(), true); } @@ -85,7 +85,7 @@ void MakeBidiStreamingCall(const std::shared_ptr& channel) { EchoResponse resp; ctx.AddMetadata("testkey", "testvalue"); auto stream = stub->BidiStream(&ctx); - for (auto i = 0; i < 10; i++) { + for (auto i = 0; i < kNumStreamingMessages; i++) { req.set_message("Hello" + std::to_string(i)); stream->Write(req); stream->Read(&resp); diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h index 419845e5f61..1cd1448a6fa 100644 --- a/test/cpp/end2end/interceptors_util.h +++ b/test/cpp/end2end/interceptors_util.h @@ -152,6 +152,8 @@ class EchoTestServiceStreamingImpl : public EchoTestService::Service { } }; +constexpr int kNumStreamingMessages = 10; + void MakeCall(const std::shared_ptr& channel); void MakeClientStreamingCall(const std::shared_ptr& channel); From c58b4a396480b29df4fec3a0a1624e64fb7fe091 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 May 2019 17:00:54 -0700 Subject: [PATCH 138/676] Clang format --- include/grpcpp/impl/codegen/call_op_set.h | 4 +--- .../client_interceptors_end2end_test.cc | 22 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index fdd0b5e91b7..95664a800fa 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -433,9 +433,7 @@ class CallOpRecvMessage { message_(nullptr), allow_not_getting_message_(false) {} - void RecvMessage(R* message) { - message_ = message; - } + void RecvMessage(R* message) { message_ = message; } // Do not change status if no message is received. void AllowNoMessage() { allow_not_getting_message_ = true; } diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 70b0ecdf585..ae4fba45532 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -502,12 +502,12 @@ class BidiStreamingRpcHijackingInterceptorFactory class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) : info_(info) { - pre_send_initial_metadata_ = false; - pre_send_message_count_ = 0; - pre_send_close_ = false; - post_recv_initial_metadata_ = false; - post_recv_message_count_ = 0; - post_recv_status_ = false; + pre_send_initial_metadata_ = false; + pre_send_message_count_ = 0; + pre_send_close_ = false; + post_recv_initial_metadata_ = false; + post_recv_message_count_ = 0; + post_recv_status_ = false; } virtual void Intercept(experimental::InterceptorBatchMethods* methods) { @@ -540,7 +540,7 @@ class LoggingInterceptor : public experimental::Interceptor { if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { // Got nothing to do here for now - pre_send_close_ = true; + pre_send_close_ = true; } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) { @@ -553,7 +553,7 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - if(resp != nullptr) { + if (resp != nullptr) { EXPECT_TRUE(resp->message().find("Hello") == 0u); post_recv_message_count_++; } @@ -590,19 +590,19 @@ class LoggingInterceptor : public experimental::Interceptor { } static void VerifyClientStreamingCall() { - VerifyCallCommon(); + VerifyCallCommon(); EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); EXPECT_EQ(post_recv_message_count_, 1); } static void VerifyServerStreamingCall() { - VerifyCallCommon(); + VerifyCallCommon(); EXPECT_EQ(pre_send_message_count_, 1); EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); } static void VerifyBidiStreamingCall() { - VerifyCallCommon(); + VerifyCallCommon(); EXPECT_EQ(pre_send_message_count_, kNumStreamingMessages); EXPECT_EQ(post_recv_message_count_, kNumStreamingMessages); } From 6a2da31a360151ad71049f06bf66e41ba85832a6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 May 2019 17:22:42 -0700 Subject: [PATCH 139/676] Remove unused variable --- test/cpp/end2end/client_interceptors_end2end_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index ae4fba45532..d548a023bd1 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -501,7 +501,7 @@ class BidiStreamingRpcHijackingInterceptorFactory class LoggingInterceptor : public experimental::Interceptor { public: - LoggingInterceptor(experimental::ClientRpcInfo* info) : info_(info) { + LoggingInterceptor(experimental::ClientRpcInfo* info) { pre_send_initial_metadata_ = false; pre_send_message_count_ = 0; pre_send_close_ = false; @@ -608,7 +608,6 @@ class LoggingInterceptor : public experimental::Interceptor { } private: - experimental::ClientRpcInfo* info_; static bool pre_send_initial_metadata_; static int pre_send_message_count_; static bool pre_send_close_; From 57cc401597f9464809ee9d9402bd448aa1e0aecc Mon Sep 17 00:00:00 2001 From: weiyongji <232589621@qq.com> Date: Sat, 25 May 2019 11:20:08 +0800 Subject: [PATCH 140/676] typo fix --- src/cpp/thread_manager/thread_manager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 2fbf309d421..62b1beebc37 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -56,7 +56,7 @@ class ThreadManager { // DoWork() // // If the return value is SHUTDOWN:, - // - ThreadManager WILL NOT call DoWork() and terminates the thead + // - ThreadManager WILL NOT call DoWork() and terminates the thread // // If the return value is TIMEOUT:, // - ThreadManager WILL NOT call DoWork() @@ -133,7 +133,7 @@ class ThreadManager { grpc_core::Thread thd_; }; - // The main funtion in ThreadManager + // The main function in ThreadManager void MainWorkLoop(); void MarkAsCompleted(WorkerThread* thd); From a2f7ce699be7678ff72870c6a164317762b1b30d Mon Sep 17 00:00:00 2001 From: weiyongji <232589621@qq.com> Date: Sat, 25 May 2019 15:07:24 +0800 Subject: [PATCH 141/676] call destroy function in test_serial() --- test/core/gpr/mpscq_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index 744cea934c5..552fe8d9687 100644 --- a/test/core/gpr/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -55,6 +55,7 @@ static void test_serial(void) { GPR_ASSERT(n->i == i); gpr_free(n); } + gpr_mpscq_destroy(&q); } typedef struct { From bd0d6fc7b6b7499f3385a92c42e853a8d55ce16e Mon Sep 17 00:00:00 2001 From: weiyongji <232589621@qq.com> Date: Sat, 25 May 2019 15:46:28 +0800 Subject: [PATCH 142/676] cancel the modification in mpscq_test.cc --- test/core/gpr/mpscq_test.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index 552fe8d9687..744cea934c5 100644 --- a/test/core/gpr/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -55,7 +55,6 @@ static void test_serial(void) { GPR_ASSERT(n->i == i); gpr_free(n); } - gpr_mpscq_destroy(&q); } typedef struct { From 13011a9787405b412b6f4126da46a71eb7339b57 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 22 May 2019 13:14:53 -0700 Subject: [PATCH 143/676] Fix PHP extension segfault --- src/php/ext/grpc/php_grpc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index f6c2f85ed47..1098075690a 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -205,7 +205,9 @@ void register_fork_handlers() { void apply_ini_settings() { if (GRPC_G(enable_fork_support)) { - putenv("GRPC_ENABLE_FORK_SUPPORT=1"); + char *enable_str = malloc(sizeof("GRPC_ENABLE_FORK_SUPPORT=1")); + strcpy(enable_str, "GRPC_ENABLE_FORK_SUPPORT=1"); + putenv(enable_str); } if (GRPC_G(poll_strategy)) { From e3c280d61373312f3f69ad786c7fbd0d7cae6f51 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 24 May 2019 15:26:05 -0700 Subject: [PATCH 144/676] build fix --- src/objective-c/tests/CronetTests/CronetUnitTests.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 595a1d19708..2473cf612be 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -40,9 +40,10 @@ #import "test/core/util/test_config.h" #define GRPC_SHADOW_BORINGSSL_SYMBOLS -#import " #import "src/core/tsi/grpc_shadow_boringssl.h" +#import + static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; do { From e24a7a3452caf1930dd1ddb6ad4949302c55c191 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 28 May 2019 09:29:40 -0700 Subject: [PATCH 145/676] Bump version to 1.21.2 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index c75a5d124fc..37046f67a83 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.1" +version = "1.21.2" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 0344ce18053..3fc8b651714 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.1 + version: 1.21.2 filegroups: - name: alts_proto headers: From ec640a53c6001321af759c13efae24350117e4bd Mon Sep 17 00:00:00 2001 From: Srini Polavarapu <35056280+srini100@users.noreply.github.com> Date: Thu, 23 May 2019 13:18:36 -0700 Subject: [PATCH 146/676] Merge pull request #19105 from gnossen/twine_check_artifacts Produce Python Wheels with a Valid long_description field --- src/python/grpcio/README.rst | 8 ++++---- tools/distrib/python/grpcio_tools/README.rst | 8 ++++---- tools/run_tests/artifacts/build_artifact_python.bat | 4 ++++ tools/run_tests/artifacts/build_artifact_python.sh | 6 ++++++ 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst index f047243f82d..04a3bcbc204 100644 --- a/src/python/grpcio/README.rst +++ b/src/python/grpcio/README.rst @@ -8,8 +8,8 @@ Installation gRPC Python is available for Linux, macOS, and Windows. -From PyPI -~~~~~~~~~ +Installing From PyPI +~~~~~~~~~~~~~~~~~~~~ If you are installing locally... @@ -37,8 +37,8 @@ n.b. On Windows and on Mac OS X one *must* have a recent release of :code:`pip` to retrieve the proper wheel from PyPI. Be sure to upgrade to the latest version! -From Source -~~~~~~~~~~~ +Installing From Source +~~~~~~~~~~~~~~~~~~~~~~ Building from source requires that you have the Python headers (usually a package named :code:`python-dev`). diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst index 32873b291fa..17816deff61 100644 --- a/tools/distrib/python/grpcio_tools/README.rst +++ b/tools/distrib/python/grpcio_tools/README.rst @@ -9,8 +9,8 @@ Installation The gRPC Python tools package is available for Linux, Mac OS X, and Windows running Python 2.7. -From PyPI -~~~~~~~~~ +Installing From PyPI +~~~~~~~~~~~~~~~~~~~~ If you are installing locally... @@ -42,8 +42,8 @@ You might also need to install Cython to handle installation via the source distribution if gRPC Python's system coverage with wheels does not happen to include your system. -From Source -~~~~~~~~~~~ +Installing From Source +~~~~~~~~~~~~~~~~~~~~~~ Building from source requires that you have the Python headers (usually a package named :code:`python-dev`) and Cython installed. It further requires a diff --git a/tools/run_tests/artifacts/build_artifact_python.bat b/tools/run_tests/artifacts/build_artifact_python.bat index 795e80dc40d..c946cd98061 100644 --- a/tools/run_tests/artifacts/build_artifact_python.bat +++ b/tools/run_tests/artifacts/build_artifact_python.bat @@ -46,6 +46,10 @@ pushd tools\distrib\python\grpcio_tools python setup.py bdist_wheel || goto :error popd +@rem Ensure the generate artifacts are valid. +python -m pip install twine +python -m twine check dist\* tools\distrib\python\grpcio_tools\dist\* || goto :error + xcopy /Y /I /S dist\* %ARTIFACT_DIR% || goto :error xcopy /Y /I /S tools\distrib\python\grpcio_tools\dist\* %ARTIFACT_DIR% || goto :error diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh index e451ced338f..c5e380fe5dc 100755 --- a/tools/run_tests/artifacts/build_artifact_python.sh +++ b/tools/run_tests/artifacts/build_artifact_python.sh @@ -130,5 +130,11 @@ then cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR" fi +# Ensure the generated artifacts are valid. +"${PYTHON}" -m virtualenv venv || { "${PYTHON}" -m pip install virtualenv && "${PYTHON}" -m virtualenv venv; } +venv/bin/python -m pip install twine +venv/bin/python -m twine check dist/* tools/distrib/python/grpcio_tools/dist/* +rm -rf venv/ + cp -r dist/* "$ARTIFACT_DIR" cp -r tools/distrib/python/grpcio_tools/dist/* "$ARTIFACT_DIR" From 66c7560fc48b90abe39ed4e7711816af4d0e851f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 28 May 2019 11:25:56 -0700 Subject: [PATCH 147/676] Fix server interceptors end2end test --- test/cpp/end2end/server_interceptors_end2end_test.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 68103f7ed34..34409fe375c 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -120,7 +120,9 @@ class LoggingInterceptor : public experimental::Interceptor { experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { EchoResponse* resp = static_cast(methods->GetRecvMessage()); - EXPECT_TRUE(resp->message().find("Hello") == 0); + if (resp != nullptr) { + EXPECT_TRUE(resp->message().find("Hello") == 0); + } } if (methods->QueryInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_CLOSE)) { From 3893a6379bd64d7a1c945819b598d7b5518eee6e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 28 May 2019 11:57:57 -0700 Subject: [PATCH 148/676] Clean up --- include/grpcpp/support/validate_service_config.h | 2 +- src/cpp/common/channel_arguments.cc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/grpcpp/support/validate_service_config.h b/include/grpcpp/support/validate_service_config.h index d5ea521a1ef..41f2c636bd9 100644 --- a/include/grpcpp/support/validate_service_config.h +++ b/include/grpcpp/support/validate_service_config.h @@ -33,4 +33,4 @@ grpc::string ValidateServiceConfigJSON(const grpc::string& service_config_json); } // namespace grpc -#endif // GRPCPP_SUPPORT_VALIDATE_SERVICE_CONFIG_H \ No newline at end of file +#endif // GRPCPP_SUPPORT_VALIDATE_SERVICE_CONFIG_H diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index f35c91572eb..932139890fe 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -23,7 +23,6 @@ #include #include #include -#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" From 56db3850af264f7224ba4b0a4611d5a28ca955f5 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 28 May 2019 14:02:39 -0700 Subject: [PATCH 149/676] Re-generate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b0c75c0811..0c8d64b7f0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.1") +set(PACKAGE_VERSION "1.21.2") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 0d148ab3cd2..6d717454fe5 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.1 -CSHARP_VERSION = 1.21.1 +CPP_VERSION = 1.21.2 +CSHARP_VERSION = 1.21.2 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ca27e4f34f3..3fc781b9355 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.1' + # version = '1.21.2' version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.1' + grpc_version = '1.21.2' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ca3225b3694..220d3af3b4b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.1' + version = '1.21.2' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 2012515bbe9..b49ccb9006a 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.1' + version = '1.21.2' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index c4a9f2889e9..673e7bce88b 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.1' + version = '1.21.2' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 31a1c448aa1..1352c4c612b 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.1' + version = '1.21.2' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 6bcbd807566..64c740e265a 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.21.1 - 1.21.1 + 1.21.2 + 1.21.2 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 619220ce4e3..0a70066da99 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.1"; } +grpc::string Version() { return "1.21.2"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 5cf75df63ab..dd609b57861 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.1.0"; + public const string CurrentAssemblyFileVersion = "1.21.2.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.1"; + public const string CurrentVersion = "1.21.2"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index c4c40fe0c66..ee7c7deba2b 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.1 + 1.21.2 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 65deb40679c..ba058320ae0 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.1 +set VERSION=1.21.2 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 8ac2dd7d303..c40eeace00e 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.1' + v = '1.21.2' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index e410f8da012..681da2b810a 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1" +#define GRPC_OBJC_VERSION_STRING @"1.21.2" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 95b112b156f..44d99eb284a 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.1" +#define GRPC_OBJC_VERSION_STRING @"1.21.2" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 3171442cc03..e76014083f7 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.1", + "version": "1.21.2", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 07a73698015..5371146a432 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.1" +#define PHP_GRPC_VERSION "1.21.2" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 4624e467fd8..3af536e9f37 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.1""" +__version__ = """1.21.2""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2451ef4a538..514df8b0ef4 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 591b5bd8fc5..961939cb2ad 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c11487af7e8..1497d526468 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 47628416c26..7731b932266 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 713746a1598..d8714f76d5b 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 3fe457f304c..2e9d29235bf 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 103b532f38f..715493c169f 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 1308aa4652e..b31c382f0c2 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.1' + VERSION = '1.21.2' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 38f7129d139..46d8d13cebc 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.1' + VERSION = '1.21.2' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 872f821c2f6..7299a21a23f 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.1' +VERSION = '1.21.2' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index c683fe91df1..b7d5569f8d3 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1 +PROJECT_NUMBER = 1.21.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 69f6a345afa..7848ef8f3a3 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.1 +PROJECT_NUMBER = 1.21.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 31ec9a74aebfe9d7036a5a1b0099e3e23be5bea1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 28 May 2019 14:23:01 -0700 Subject: [PATCH 150/676] More LB policy API improvements. --- .../filters/client_channel/client_channel.cc | 164 +++++++++++------- .../ext/filters/client_channel/lb_policy.cc | 18 +- .../ext/filters/client_channel/lb_policy.h | 154 ++++++++-------- .../client_channel/lb_policy/grpclb/grpclb.cc | 43 ++--- .../lb_policy/pick_first/pick_first.cc | 14 +- .../lb_policy/round_robin/round_robin.cc | 17 +- .../client_channel/lb_policy/xds/xds.cc | 56 +++--- .../client_channel/lb_policy_factory.h | 2 +- .../client_channel/lb_policy_registry.cc | 2 +- .../client_channel/lb_policy_registry.h | 2 +- .../client_channel/resolver_result_parsing.cc | 2 +- .../client_channel/resolver_result_parsing.h | 6 +- .../client_channel/resolving_lb_policy.cc | 6 +- .../client_channel/resolving_lb_policy.h | 8 +- test/core/util/test_lb_policies.cc | 34 ++-- 15 files changed, 291 insertions(+), 237 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index c0586d459b2..5717d3e66d2 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -105,7 +105,6 @@ namespace { class ChannelData { public: struct QueuedPick { - LoadBalancingPolicy::PickArgs pick; grpc_call_element* elem; QueuedPick* next = nullptr; }; @@ -223,7 +222,7 @@ class ChannelData { static bool ProcessResolverResultLocked( void* arg, Resolver::Result* result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config, + RefCountedPtr* lb_policy_config, grpc_error** service_config_error); grpc_error* DoPingLocked(grpc_transport_op* op); @@ -236,7 +235,7 @@ class ChannelData { const Resolver::Result& resolver_result, const internal::ClientChannelGlobalParsedConfig* parsed_service_config, UniquePtr* lb_policy_name, - RefCountedPtr* lb_policy_config); + RefCountedPtr* lb_policy_config); // // Fields set at construction and never modified. @@ -314,6 +313,16 @@ class CallData { private: class QueuedPickCanceller; + class LbCallState : public LoadBalancingPolicy::CallState { + public: + explicit LbCallState(CallData* calld) : calld_(calld) {} + + void* Alloc(size_t size) override { return calld_->arena_->Alloc(size); } + + private: + CallData* calld_; + }; + // State used for starting a retryable batch on a subchannel call. // This provides its own grpc_transport_stream_op_batch and other data // structures needed to populate the ops in the batch. @@ -449,8 +458,9 @@ class CallData { grpc_call_element* elem, SubchannelCallBatchData* batch_data, SubchannelCallRetryState* retry_state); - static void MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( - const LoadBalancingPolicy::PickArgs& pick, + static void RecvTrailingMetadataReadyForLoadBalancingPolicy( + void* arg, grpc_error* error); + void MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( grpc_transport_stream_op_batch* batch); // Returns the index into pending_batches_ to be used for batch. @@ -640,8 +650,19 @@ class CallData { bool pick_queued_ = false; bool service_config_applied_ = false; QueuedPickCanceller* pick_canceller_ = nullptr; + LbCallState lb_call_state_; + RefCountedPtr connected_subchannel_; + void (*lb_recv_trailing_metadata_ready_)( + void* user_data, grpc_metadata_batch* recv_trailing_metadata, + LoadBalancingPolicy::CallState* call_state) = nullptr; + void* lb_recv_trailing_metadata_ready_user_data_ = nullptr; grpc_closure pick_closure_; + // For intercepting recv_trailing_metadata_ready for the LB policy. + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_polling_entity* pollent_ = nullptr; // Batches are added to this list when received from above. @@ -1143,7 +1164,7 @@ void ChannelData::ProcessLbPolicy( const Resolver::Result& resolver_result, const internal::ClientChannelGlobalParsedConfig* parsed_service_config, UniquePtr* lb_policy_name, - RefCountedPtr* lb_policy_config) { + RefCountedPtr* lb_policy_config) { // Prefer the LB policy name found in the service config. if (parsed_service_config != nullptr && parsed_service_config->parsed_lb_config() != nullptr) { @@ -1191,7 +1212,7 @@ void ChannelData::ProcessLbPolicy( // resolver result update. bool ChannelData::ProcessResolverResultLocked( void* arg, Resolver::Result* result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config, + RefCountedPtr* lb_policy_config, grpc_error** service_config_error) { ChannelData* chand = static_cast(arg); RefCountedPtr service_config; @@ -1312,19 +1333,18 @@ grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { if (grpc_connectivity_state_check(&state_tracker_) != GRPC_CHANNEL_READY) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected"); } - LoadBalancingPolicy::PickArgs pick; - grpc_error* error = GRPC_ERROR_NONE; - picker_->Pick(&pick, &error); - if (pick.connected_subchannel != nullptr) { - pick.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); + LoadBalancingPolicy::PickResult result = + picker_->Pick(LoadBalancingPolicy::PickArgs()); + if (result.connected_subchannel != nullptr) { + result.connected_subchannel->Ping(op->send_ping.on_initiate, + op->send_ping.on_ack); } else { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + if (result.error == GRPC_ERROR_NONE) { + result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "LB policy dropped call on ping"); } } - return error; + return result.error; } void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { @@ -1505,6 +1525,7 @@ CallData::CallData(grpc_call_element* elem, const ChannelData& chand, owning_call_(args.call_stack), call_combiner_(args.call_combiner), call_context_(args.context), + lb_call_state_(this), pending_send_initial_metadata_(false), pending_send_message_(false), pending_send_trailing_metadata_(false), @@ -1737,18 +1758,30 @@ void CallData::FreeCachedSendOpDataForCompletedBatch( // LB recv_trailing_metadata_ready handling // +void CallData::RecvTrailingMetadataReadyForLoadBalancingPolicy( + void* arg, grpc_error* error) { + CallData* calld = static_cast(arg); + // Invoke callback to LB policy. + calld->lb_recv_trailing_metadata_ready_( + calld->lb_recv_trailing_metadata_ready_user_data_, + calld->recv_trailing_metadata_, &calld->lb_call_state_); + // Chain to original callback. + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(error)); +} + void CallData::MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( - const LoadBalancingPolicy::PickArgs& pick, grpc_transport_stream_op_batch* batch) { - if (pick.recv_trailing_metadata_ready != nullptr) { - *pick.original_recv_trailing_metadata_ready = + if (lb_recv_trailing_metadata_ready_ != nullptr) { + recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + original_recv_trailing_metadata_ready_ = batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecvTrailingMetadataReadyForLoadBalancingPolicy, this, + grpc_schedule_on_exec_ctx); batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - pick.recv_trailing_metadata_ready; - if (pick.recv_trailing_metadata != nullptr) { - *pick.recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - } + &recv_trailing_metadata_ready_; } } @@ -1894,8 +1927,7 @@ void CallData::PendingBatchesFail( grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { if (batch->recv_trailing_metadata) { - MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, - batch); + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(batch); } batch->handler_private.extra_arg = this; GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -1949,8 +1981,7 @@ void CallData::PendingBatchesResume(grpc_call_element* elem) { grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { if (batch->recv_trailing_metadata) { - MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(pick_.pick, - batch); + MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(batch); } batch->handler_private.extra_arg = subchannel_call_.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -2011,7 +2042,7 @@ void CallData::DoRetry(grpc_call_element* elem, GPR_ASSERT(retry_policy != nullptr); // Reset subchannel call and connected subchannel. subchannel_call_.reset(); - pick_.pick.connected_subchannel.reset(); + connected_subchannel_.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { @@ -2868,7 +2899,7 @@ void CallData::AddRetriableRecvTrailingMetadataOp( .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy( - pick_.pick, &batch_data->batch); + &batch_data->batch); } void CallData::StartInternalRecvTrailingMetadata(grpc_call_element* elem) { @@ -3135,8 +3166,7 @@ void CallData::CreateSubchannelCall(grpc_call_element* elem) { // need to use a separate call context for each subchannel call. call_context_, call_combiner_, parent_data_size}; grpc_error* error = GRPC_ERROR_NONE; - subchannel_call_ = - pick_.pick.connected_subchannel->CreateCall(call_args, &error); + subchannel_call_ = connected_subchannel_->CreateCall(call_args, &error); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, this, subchannel_call_.get(), grpc_error_string(error)); @@ -3297,13 +3327,14 @@ void CallData::MaybeApplyServiceConfigToCallLocked(grpc_call_element* elem) { } } -const char* PickResultName(LoadBalancingPolicy::PickResult result) { - switch (result) { - case LoadBalancingPolicy::PICK_COMPLETE: +const char* PickResultTypeName( + LoadBalancingPolicy::PickResult::ResultType type) { + switch (type) { + case LoadBalancingPolicy::PickResult::PICK_COMPLETE: return "COMPLETE"; - case LoadBalancingPolicy::PICK_QUEUE: + case LoadBalancingPolicy::PickResult::PICK_QUEUE: return "QUEUE"; - case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: + case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: return "TRANSIENT_FAILURE"; } GPR_UNREACHABLE_CODE(return "UNKNOWN"); @@ -3313,8 +3344,10 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); CallData* calld = static_cast(elem->call_data); ChannelData* chand = static_cast(elem->channel_data); - GPR_ASSERT(calld->pick_.pick.connected_subchannel == nullptr); + GPR_ASSERT(calld->connected_subchannel_ == nullptr); GPR_ASSERT(calld->subchannel_call_ == nullptr); + // Apply service config to call if needed. + calld->MaybeApplyServiceConfigToCallLocked(elem); // If this is a retry, use the send_initial_metadata payload that // we've cached; otherwise, use the pending batch. The // send_initial_metadata batch will be the first pending batch in the @@ -3325,58 +3358,58 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { // allocate the subchannel batch earlier so that we can give the // subchannel's copy of the metadata batch (which is copied for each // attempt) to the LB policy instead the one from the parent channel. - calld->pick_.pick.initial_metadata = + LoadBalancingPolicy::PickArgs pick_args; + pick_args.call_state = &calld->lb_call_state_; + pick_args.initial_metadata = calld->seen_send_initial_metadata_ ? &calld->send_initial_metadata_ : calld->pending_batches_[0] .batch->payload->send_initial_metadata.send_initial_metadata; - uint32_t* send_initial_metadata_flags = + // Grab initial metadata flags so that we can check later if the call has + // wait_for_ready enabled. + const uint32_t send_initial_metadata_flags = calld->seen_send_initial_metadata_ - ? &calld->send_initial_metadata_flags_ - : &calld->pending_batches_[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - // Apply service config to call if needed. - calld->MaybeApplyServiceConfigToCallLocked(elem); + ? calld->send_initial_metadata_flags_ + : calld->pending_batches_[0] + .batch->payload->send_initial_metadata + .send_initial_metadata_flags; // When done, we schedule this closure to leave the data plane combiner. GRPC_CLOSURE_INIT(&calld->pick_closure_, PickDone, elem, grpc_schedule_on_exec_ctx); // Attempt pick. - error = GRPC_ERROR_NONE; - auto pick_result = chand->picker()->Pick(&calld->pick_.pick, &error); + auto result = chand->picker()->Pick(pick_args); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " "error=%s)", - chand, calld, PickResultName(pick_result), - calld->pick_.pick.connected_subchannel.get(), - grpc_error_string(error)); + chand, calld, PickResultTypeName(result.type), + result.connected_subchannel.get(), grpc_error_string(result.error)); } - switch (pick_result) { - case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: { + switch (result.type) { + case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: { // If we're shutting down, fail all RPCs. grpc_error* disconnect_error = chand->disconnect_error(); if (disconnect_error != GRPC_ERROR_NONE) { - GRPC_ERROR_UNREF(error); + GRPC_ERROR_UNREF(result.error); GRPC_CLOSURE_SCHED(&calld->pick_closure_, GRPC_ERROR_REF(disconnect_error)); break; } // If wait_for_ready is false, then the error indicates the RPC // attempt's final status. - if ((*send_initial_metadata_flags & + if ((send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { // Retry if appropriate; otherwise, fail. grpc_status_code status = GRPC_STATUS_OK; - grpc_error_get_status(error, calld->deadline_, &status, nullptr, + grpc_error_get_status(result.error, calld->deadline_, &status, nullptr, nullptr, nullptr); if (!calld->enable_retries_ || !calld->MaybeRetry(elem, nullptr /* batch_data */, status, nullptr /* server_pushback_md */)) { grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Failed to pick subchannel", &error, 1); - GRPC_ERROR_UNREF(error); + "Failed to pick subchannel", &result.error, 1); + GRPC_ERROR_UNREF(result.error); GRPC_CLOSURE_SCHED(&calld->pick_closure_, new_error); } if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); @@ -3384,19 +3417,24 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { } // If wait_for_ready is true, then queue to retry when we get a new // picker. - GRPC_ERROR_UNREF(error); + GRPC_ERROR_UNREF(result.error); } // Fallthrough - case LoadBalancingPolicy::PICK_QUEUE: + case LoadBalancingPolicy::PickResult::PICK_QUEUE: if (!calld->pick_queued_) calld->AddCallToQueuedPicksLocked(elem); break; default: // PICK_COMPLETE // Handle drops. - if (GPR_UNLIKELY(calld->pick_.pick.connected_subchannel == nullptr)) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + if (GPR_UNLIKELY(result.connected_subchannel == nullptr)) { + result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Call dropped by load balancing policy"); } - GRPC_CLOSURE_SCHED(&calld->pick_closure_, error); + calld->connected_subchannel_ = std::move(result.connected_subchannel); + calld->lb_recv_trailing_metadata_ready_ = + result.recv_trailing_metadata_ready; + calld->lb_recv_trailing_metadata_ready_user_data_ = + result.recv_trailing_metadata_ready_user_data; + GRPC_CLOSURE_SCHED(&calld->pick_closure_, result.error); if (calld->pick_queued_) calld->RemoveCallFromQueuedPicksLocked(elem); } } diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 6fa799343ca..3e4d3703c82 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -105,7 +105,7 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( // LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick( - PickArgs* pick, grpc_error** error) { + PickArgs args) { // We invoke the parent's ExitIdleLocked() via a closure instead // of doing it directly here, for two reasons: // 1. ExitIdleLocked() may cause the policy's state to change and @@ -125,7 +125,9 @@ LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick( grpc_combiner_scheduler(parent_->combiner())), GRPC_ERROR_NONE); } - return PICK_QUEUE; + PickResult result; + result.type = PickResult::PICK_QUEUE; + return result; } void LoadBalancingPolicy::QueuePicker::CallExitIdle(void* arg, @@ -135,4 +137,16 @@ void LoadBalancingPolicy::QueuePicker::CallExitIdle(void* arg, parent->Unref(); } +// +// LoadBalancingPolicy::TransientFailurePicker +// + +LoadBalancingPolicy::PickResult +LoadBalancingPolicy::TransientFailurePicker::Pick(PickArgs args) { + PickResult result; + result.type = PickResult::PICK_TRANSIENT_FAILURE; + result.error = GRPC_ERROR_REF(error_); + return result; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 2ac7df63b7d..5920254a9ef 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -32,21 +32,9 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/connectivity_state.h" -extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; - namespace grpc_core { -/// Interface for parsed forms of load balancing configs found in a service -/// config. -class ParsedLoadBalancingConfig : public RefCounted { - public: - virtual ~ParsedLoadBalancingConfig() = default; - - // Returns the load balancing policy name - virtual const char* name() const GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS; -}; +extern DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; /// Interface for load balancing policies. /// @@ -89,66 +77,77 @@ class ParsedLoadBalancingConfig : public RefCounted { // interested_parties() hooks from the API. class LoadBalancingPolicy : public InternallyRefCounted { public: + /// Interface for accessing per-call state. + class CallState { + public: + CallState() = default; + virtual ~CallState() = default; + + /// Allocates memory associated with the call, which will be + /// automatically freed when the call is complete. + /// It is more efficient to use this than to allocate memory directly + /// for allocations that need to be made on a per-call basis. + virtual void* Alloc(size_t size) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + /// Arguments used when picking a subchannel for an RPC. struct PickArgs { - /// - /// Input parameters. - /// /// Initial metadata associated with the picking call. /// The LB policy may use the existing metadata to influence its routing /// decision, and it may add new metadata elements to be sent with the /// call to the chosen backend. // TODO(roth): Provide a more generic metadata API here. grpc_metadata_batch* initial_metadata = nullptr; - /// Storage for LB token in \a initial_metadata, or nullptr if not used. - // TODO(roth): Remove this from the API. Maybe have the LB policy - // allocate this on the arena instead? - grpc_linked_mdelem lb_token_mdelem_storage; - /// - /// Output parameters. - /// - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; - /// Callback set by lb policy to be notified of trailing metadata. - /// The callback must be scheduled on grpc_schedule_on_exec_ctx. - // TODO(roth): Provide a cleaner callback API. - grpc_closure* recv_trailing_metadata_ready = nullptr; - /// The address that will be set to point to the original - /// recv_trailing_metadata_ready callback, to be invoked by the LB - /// policy's recv_trailing_metadata_ready callback when complete. - /// Must be non-null if recv_trailing_metadata_ready is non-null. - // TODO(roth): Consider making the recv_trailing_metadata closure a - // synchronous callback, in which case it is not responsible for - // chaining to the next callback, so this can be removed from the API. - grpc_closure** original_recv_trailing_metadata_ready = nullptr; - /// If this is not nullptr, then the client channel will point it to the - /// call's trailing metadata before invoking recv_trailing_metadata_ready. - /// If this is nullptr, then the callback will still be called. - /// The lb does not have ownership of the metadata. - // TODO(roth): If we make this a synchronous callback, then this can - // be passed to the callback as a parameter and can be removed from - // the API here. - grpc_metadata_batch** recv_trailing_metadata = nullptr; + /// An interface for accessing call state. Can be used to allocate + /// data associated with the call in an efficient way. + CallState* call_state; }; /// The result of picking a subchannel for an RPC. - enum PickResult { - // Pick complete. If connected_subchannel is non-null, client channel - // can immediately proceed with the call on connected_subchannel; - // otherwise, call should be dropped. - PICK_COMPLETE, - // Pick cannot be completed until something changes on the control - // plane. Client channel will queue the pick and try again the - // next time the picker is updated. - PICK_QUEUE, - // LB policy is in transient failure. If the pick is wait_for_ready, - // client channel will wait for the next picker and try again; - // otherwise, the call will be failed immediately (although it may - // be retried if the client channel is configured to do so). - // The Pick() method will set its error parameter if this value is - // returned. - PICK_TRANSIENT_FAILURE, + struct PickResult { + enum ResultType { + /// Pick complete. If connected_subchannel is non-null, client channel + /// can immediately proceed with the call on connected_subchannel; + /// otherwise, call should be dropped. + PICK_COMPLETE, + /// Pick cannot be completed until something changes on the control + /// plane. Client channel will queue the pick and try again the + /// next time the picker is updated. + PICK_QUEUE, + /// LB policy is in transient failure. If the pick is wait_for_ready, + /// client channel will wait for the next picker and try again; + /// otherwise, the call will be failed immediately (although it may + /// be retried if the client channel is configured to do so). + /// The Pick() method will set its error parameter if this value is + /// returned. + PICK_TRANSIENT_FAILURE, + }; + ResultType type; + + /// Used only if type is PICK_COMPLETE. Will be set to the selected + /// subchannel, or nullptr if the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; + + /// Used only if type is PICK_TRANSIENT_FAILURE. + /// Error to be set when returning a transient failure. + // TODO(roth): Replace this with something similar to grpc::Status, + // so that we don't expose grpc_error to this API. + grpc_error* error = GRPC_ERROR_NONE; + + /// Used only if type is PICK_COMPLETE. + /// Callback set by lb policy to be notified of trailing metadata. + /// The user_data argument will be set to the + /// recv_trailing_metadata_ready_user_data field. + /// recv_trailing_metadata will be set to the metadata, which may be + /// modified by the callback. The callback does not take ownership, + /// however, so any data that needs to be used after returning must + /// be copied. + void (*recv_trailing_metadata_ready)( + void* user_data, grpc_metadata_batch* recv_trailing_metadata, + CallState* call_state) = nullptr; + void* recv_trailing_metadata_ready_user_data = nullptr; }; /// A subchannel picker is the object used to pick the subchannel to @@ -162,17 +161,14 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// live in the LB policy object itself. /// /// Currently, pickers are always accessed from within the - /// client_channel combiner, so they do not have to be thread-safe. - // TODO(roth): In a subsequent PR, split the data plane work (i.e., - // the interaction with the picker) and the control plane work (i.e., - // the interaction with the LB policy) into two different - // synchronization mechanisms, to avoid lock contention between the two. + /// client_channel data plane combiner, so they do not have to be + /// thread-safe. class SubchannelPicker { public: SubchannelPicker() = default; virtual ~SubchannelPicker() = default; - virtual PickResult Pick(PickArgs* pick, grpc_error** error) GRPC_ABSTRACT; + virtual PickResult Pick(PickArgs args) GRPC_ABSTRACT; GRPC_ABSTRACT_BASE_CLASS }; @@ -208,11 +204,24 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS }; + /// Interface for configuration data used by an LB policy implementation. + /// Individual implementations will create a subclass that adds methods to + /// return the parameters they need. + class Config : public RefCounted { + public: + virtual ~Config() = default; + + // Returns the load balancing policy name + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + /// Data passed to the UpdateLocked() method when new addresses and /// config are available. struct UpdateArgs { ServerAddressList addresses; - RefCountedPtr config; + RefCountedPtr config; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is @@ -291,7 +300,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { explicit QueuePicker(RefCountedPtr parent) : parent_(std::move(parent)) {} - PickResult Pick(PickArgs* pick, grpc_error** error) override; + PickResult Pick(PickArgs args) override; private: static void CallExitIdle(void* arg, grpc_error* error); @@ -306,10 +315,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { explicit TransientFailurePicker(grpc_error* error) : error_(error) {} ~TransientFailurePicker() override { GRPC_ERROR_UNREF(error_); } - PickResult Pick(PickArgs* pick, grpc_error** error) override { - *error = GRPC_ERROR_REF(error_); - return PICK_TRANSIENT_FAILURE; - } + PickResult Pick(PickArgs args) override; private: grpc_error* error_; diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ed6e8de3f21..2c652e4c6e6 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -118,19 +118,19 @@ namespace { constexpr char kGrpclb[] = "grpclb"; -class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { +class ParsedGrpcLbConfig : public LoadBalancingPolicy::Config { public: explicit ParsedGrpcLbConfig( - RefCountedPtr child_policy) + RefCountedPtr child_policy) : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } - RefCountedPtr child_policy() const { + RefCountedPtr child_policy() const { return child_policy_; } private: - RefCountedPtr child_policy_; + RefCountedPtr child_policy_; }; class GrpcLb : public LoadBalancingPolicy { @@ -274,7 +274,7 @@ class GrpcLb : public LoadBalancingPolicy { child_picker_(std::move(child_picker)), client_stats_(std::move(client_stats)) {} - PickResult Pick(PickArgs* pick, grpc_error** error) override; + PickResult Pick(PickArgs args) override; private: // Storing the address for logging, but not holding a ref. @@ -394,7 +394,7 @@ class GrpcLb : public LoadBalancingPolicy { // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; // The child policy config. - RefCountedPtr child_policy_config_; + RefCountedPtr child_policy_config_; // Child policy in state READY. bool child_policy_ready_ = false; }; @@ -561,7 +561,8 @@ const char* GrpcLb::Serverlist::ShouldDrop() { // GrpcLb::Picker // -GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs* pick, grpc_error** error) { +GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) { + PickResult result; // Check if we should drop the call. const char* drop_token = serverlist_->ShouldDrop(); if (drop_token != nullptr) { @@ -573,26 +574,28 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs* pick, grpc_error** error) { if (client_stats_ != nullptr) { client_stats_->AddCallDropped(drop_token); } - return PICK_COMPLETE; + result.type = PickResult::PICK_COMPLETE; + return result; } // Forward pick to child policy. - PickResult result = child_picker_->Pick(pick, error); + result = child_picker_->Pick(args); // If pick succeeded, add LB token to initial metadata. - if (result == PickResult::PICK_COMPLETE && - pick->connected_subchannel != nullptr) { + if (result.type == PickResult::PICK_COMPLETE && + result.connected_subchannel != nullptr) { const grpc_arg* arg = grpc_channel_args_find( - pick->connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); if (arg == nullptr) { gpr_log(GPR_ERROR, - "[grpclb %p picker %p] No LB token for connected subchannel " - "pick %p", - parent_, this, pick); + "[grpclb %p picker %p] No LB token for connected subchannel %p", + parent_, this, result.connected_subchannel.get()); abort(); } grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + grpc_linked_mdelem* mdelem_storage = static_cast( + args.call_state->Alloc(sizeof(grpc_linked_mdelem))); GPR_ASSERT(grpc_metadata_batch_add_tail( - pick->initial_metadata, &pick->lb_token_mdelem_storage, + args.initial_metadata, mdelem_storage, GRPC_MDELEM_REF(lb_token)) == GRPC_ERROR_NONE); GrpcLbClientStats* client_stats = static_cast( grpc_mdelem_get_user_data(lb_token, GrpcLbClientStats::Destroy)); @@ -1800,15 +1803,15 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kGrpclb; } - RefCountedPtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (json == nullptr) { - return RefCountedPtr( + return RefCountedPtr( New(nullptr)); } InlinedVector error_list; - RefCountedPtr child_policy; + RefCountedPtr child_policy; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; @@ -1826,7 +1829,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } } if (error_list.empty()) { - return RefCountedPtr( + return RefCountedPtr( New(std::move(child_policy))); } else { *error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list); diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 199e973e72c..1b0dd230b49 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -115,9 +115,11 @@ class PickFirst : public LoadBalancingPolicy { explicit Picker(RefCountedPtr connected_subchannel) : connected_subchannel_(std::move(connected_subchannel)) {} - PickResult Pick(PickArgs* pick, grpc_error** error) override { - pick->connected_subchannel = connected_subchannel_; - return PICK_COMPLETE; + PickResult Pick(PickArgs args) override { + PickResult result; + result.type = PickResult::PICK_COMPLETE; + result.connected_subchannel = connected_subchannel_; + return result; } private: @@ -527,7 +529,7 @@ void PickFirst::PickFirstSubchannelData:: } } -class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { +class ParsedPickFirstConfig : public LoadBalancingPolicy::Config { public: const char* name() const override { return kPickFirst; } }; @@ -545,12 +547,12 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kPickFirst; } - RefCountedPtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { if (json != nullptr) { GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); } - return RefCountedPtr( + return RefCountedPtr( New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 1693032ea24..0b9915de28e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -149,7 +149,7 @@ class RoundRobin : public LoadBalancingPolicy { public: Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); - PickResult Pick(PickArgs* pick, grpc_error** error) override; + PickResult Pick(PickArgs args) override; private: // Using pointer value only, no ref held -- do not dereference! @@ -220,8 +220,7 @@ RoundRobin::Picker::Picker(RoundRobin* parent, } } -RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick, - grpc_error** error) { +RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs args) { last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, @@ -230,8 +229,10 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick, parent_, this, last_picked_index_, subchannels_[last_picked_index_].get()); } - pick->connected_subchannel = subchannels_[last_picked_index_]; - return PICK_COMPLETE; + PickResult result; + result.type = PickResult::PICK_COMPLETE; + result.connected_subchannel = subchannels_[last_picked_index_]; + return result; } // @@ -503,7 +504,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } -class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { +class ParsedRoundRobinConfig : public LoadBalancingPolicy::Config { public: const char* name() const override { return kRoundRobin; } }; @@ -521,12 +522,12 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kRoundRobin; } - RefCountedPtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { if (json != nullptr) { GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); } - return RefCountedPtr( + return RefCountedPtr( New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 819bad6c00d..d70042af229 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -120,11 +120,11 @@ constexpr char kXds[] = "xds_experimental"; constexpr char kDefaultLocalityName[] = "xds_default_locality"; constexpr uint32_t kDefaultLocalityWeight = 3; -class ParsedXdsConfig : public ParsedLoadBalancingConfig { +class ParsedXdsConfig : public LoadBalancingPolicy::Config { public: ParsedXdsConfig(const char* balancer_name, - RefCountedPtr child_policy, - RefCountedPtr fallback_policy) + RefCountedPtr child_policy, + RefCountedPtr fallback_policy) : balancer_name_(balancer_name), child_policy_(std::move(child_policy)), fallback_policy_(std::move(fallback_policy)) {} @@ -133,18 +133,18 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { const char* balancer_name() const { return balancer_name_; }; - RefCountedPtr child_policy() const { + RefCountedPtr child_policy() const { return child_policy_; } - RefCountedPtr fallback_policy() const { + RefCountedPtr fallback_policy() const { return fallback_policy_; } private: const char* balancer_name_ = nullptr; - RefCountedPtr child_policy_; - RefCountedPtr fallback_policy_; + RefCountedPtr child_policy_; + RefCountedPtr fallback_policy_; }; class XdsLb : public LoadBalancingPolicy { @@ -300,9 +300,7 @@ class XdsLb : public LoadBalancingPolicy { public: explicit PickerRef(UniquePtr picker) : picker_(std::move(picker)) {} - PickResult Pick(PickArgs* pick, grpc_error** error) { - return picker_->Pick(pick, error); - } + PickResult Pick(PickArgs args) { return picker_->Pick(args); } private: UniquePtr picker_; @@ -322,12 +320,11 @@ class XdsLb : public LoadBalancingPolicy { : client_stats_(std::move(client_stats)), pickers_(std::move(pickers)) {} - PickResult Pick(PickArgs* pick, grpc_error** error) override; + PickResult Pick(PickArgs args) override; private: // Calls the picker of the locality that the key falls within - PickResult PickFromLocality(const uint32_t key, PickArgs* pick, - grpc_error** error); + PickResult PickFromLocality(const uint32_t key, PickArgs args); RefCountedPtr client_stats_; PickerList pickers_; }; @@ -363,7 +360,7 @@ class XdsLb : public LoadBalancingPolicy { ~LocalityEntry() = default; void UpdateLocked(xds_grpclb_serverlist* serverlist, - ParsedLoadBalancingConfig* child_policy_config, + LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); @@ -410,7 +407,7 @@ class XdsLb : public LoadBalancingPolicy { }; void UpdateLocked(const LocalityList& locality_list, - ParsedLoadBalancingConfig* child_policy_config, + LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); @@ -506,7 +503,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the fallback backends. - RefCountedPtr fallback_policy_config_; + RefCountedPtr fallback_policy_config_; // Lock held when modifying the value of fallback_policy_ or // pending_fallback_policy_. Mutex fallback_policy_mu_; @@ -515,7 +512,7 @@ class XdsLb : public LoadBalancingPolicy { OrphanablePtr pending_fallback_policy_; // The policy to use for the backends. - RefCountedPtr child_policy_config_; + RefCountedPtr child_policy_config_; // Map of policies to use in the backend LocalityMap locality_map_; // TODO(mhaidry) : Add support for multiple maps of localities @@ -530,25 +527,24 @@ class XdsLb : public LoadBalancingPolicy { // XdsLb::Picker // -XdsLb::PickResult XdsLb::Picker::Pick(PickArgs* pick, grpc_error** error) { +XdsLb::PickResult XdsLb::Picker::Pick(PickArgs args) { // TODO(roth): Add support for drop handling. // Generate a random number between 0 and the total weight const uint32_t key = (rand() * pickers_[pickers_.size() - 1].first) / RAND_MAX; // Forward pick to whichever locality maps to the range in which the // random number falls in. - PickResult result = PickFromLocality(key, pick, error); + PickResult result = PickFromLocality(key, args); // If pick succeeded, add client stats. - if (result == PickResult::PICK_COMPLETE && - pick->connected_subchannel != nullptr && client_stats_ != nullptr) { + if (result.type == PickResult::PICK_COMPLETE && + result.connected_subchannel != nullptr && client_stats_ != nullptr) { // TODO(roth): Add support for client stats. } return result; } XdsLb::PickResult XdsLb::Picker::PickFromLocality(const uint32_t key, - PickArgs* pick, - grpc_error** error) { + PickArgs args) { size_t mid = 0; size_t start_index = 0; size_t end_index = pickers_.size() - 1; @@ -566,7 +562,7 @@ XdsLb::PickResult XdsLb::Picker::PickFromLocality(const uint32_t key, } if (index == 0) index = start_index; GPR_ASSERT(pickers_[index].first > key); - return pickers_[index].second->Pick(pick, error); + return pickers_[index].second->Pick(args); } // @@ -1744,7 +1740,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - ParsedLoadBalancingConfig* child_policy_config, + LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1839,7 +1835,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - ParsedLoadBalancingConfig* child_policy_config, + LoadBalancingPolicy::Config* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // Construct update args. @@ -2158,7 +2154,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kXds; } - RefCountedPtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (json == nullptr) { @@ -2174,8 +2170,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { InlinedVector error_list; const char* balancer_name = nullptr; - RefCountedPtr child_policy; - RefCountedPtr fallback_policy; + RefCountedPtr child_policy; + RefCountedPtr fallback_policy; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; @@ -2221,7 +2217,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { "field:balancerName error:not found")); } if (error_list.empty()) { - return RefCountedPtr(New( + return RefCountedPtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list); diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index aaf3e959542..3b8c9faa180 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -37,7 +37,7 @@ class LoadBalancingPolicyFactory { /// Caller does NOT take ownership of result. virtual const char* name() const GRPC_ABSTRACT; - virtual RefCountedPtr ParseLoadBalancingConfig( + virtual RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT; virtual ~LoadBalancingPolicyFactory() {} diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index 973aa26d0f6..20099b52d6c 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -176,7 +176,7 @@ grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, } } // namespace -RefCountedPtr +RefCountedPtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 6820cfc9334..c5f02953a1b 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -56,7 +56,7 @@ class LoadBalancingPolicyRegistry { /// Returns a parsed object of the load balancing policy to be used from a /// LoadBalancingConfig array \a json. - static RefCountedPtr ParseLoadBalancingConfig( + static RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error); }; diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 6a811a2d936..3a1960bfded 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -268,7 +268,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - RefCountedPtr parsed_lb_config; + RefCountedPtr parsed_lb_config; UniquePtr lb_policy_name; Optional retry_throttling; const char* health_check_service_name = nullptr; diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 7750791c779..d0a0456875d 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -45,7 +45,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { }; ClientChannelGlobalParsedConfig( - RefCountedPtr parsed_lb_config, + RefCountedPtr parsed_lb_config, UniquePtr parsed_deprecated_lb_policy, const Optional& retry_throttling, const char* health_check_service_name) @@ -58,7 +58,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { return retry_throttling_; } - RefCountedPtr parsed_lb_config() const { + RefCountedPtr parsed_lb_config() const { return parsed_lb_config_; } @@ -71,7 +71,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { } private: - RefCountedPtr parsed_lb_config_; + RefCountedPtr parsed_lb_config_; UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; const char* health_check_service_name_; diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 4e383f65dd1..3fe2ee74c92 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -184,7 +184,7 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - RefCountedPtr child_lb_config, + RefCountedPtr child_lb_config, grpc_error** error) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), @@ -333,7 +333,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, - RefCountedPtr lb_policy_config, + RefCountedPtr lb_policy_config, Resolver::Result result, TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store @@ -530,7 +530,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config; + RefCountedPtr lb_policy_config; bool service_config_changed = false; char* service_config_error_string = nullptr; if (process_resolver_result_ != nullptr) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 0ca6c9563f9..cc9f3176cce 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -57,7 +57,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - RefCountedPtr child_lb_config, + RefCountedPtr child_lb_config, grpc_error** error); // Private ctor, to be used by client_channel only! @@ -70,7 +70,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // should set the channel to be in TRANSIENT_FAILURE. typedef bool (*ProcessResolverResultCallback)( void* user_data, Resolver::Result* result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config, + RefCountedPtr* lb_policy_config, grpc_error** service_config_error); // If error is set when this returns, then construction failed, and // the caller may not use the new object. @@ -109,7 +109,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void OnResolverError(grpc_error* error); void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, - RefCountedPtr lb_policy_config, + RefCountedPtr lb_policy_config, Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, @@ -126,7 +126,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - RefCountedPtr child_lb_config_; + RefCountedPtr child_lb_config_; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index b871f04bc9e..bd28422bcd1 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -120,10 +120,12 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy cb_(cb), user_data_(user_data) {} - PickResult Pick(PickArgs* pick, grpc_error** error) override { - PickResult result = delegate_picker_->Pick(pick, error); - if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { - New(pick, cb_, user_data_); // deletes itself + PickResult Pick(PickArgs args) override { + PickResult result = delegate_picker_->Pick(args); + if (result.type == PickResult::PICK_COMPLETE && + result.connected_subchannel != nullptr) { + new (args.call_state->Alloc(sizeof(TrailingMetadataHandler))) + TrailingMetadataHandler(&result, cb_, user_data_); } return result; } @@ -169,35 +171,27 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy class TrailingMetadataHandler { public: - TrailingMetadataHandler(PickArgs* pick, + TrailingMetadataHandler(PickResult* result, InterceptRecvTrailingMetadataCallback cb, void* user_data) : cb_(cb), user_data_(user_data) { - GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, - RecordRecvTrailingMetadata, this, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->original_recv_trailing_metadata_ready = - &original_recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; + result->recv_trailing_metadata_ready = &RecordRecvTrailingMetadata; + result->recv_trailing_metadata_ready_user_data = this; } private: - static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + static void RecordRecvTrailingMetadata( + void* arg, grpc_metadata_batch* recv_trailing_metadata, + CallState* call_state) { TrailingMetadataHandler* self = static_cast(arg); - GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + GPR_ASSERT(recv_trailing_metadata != nullptr); self->cb_(self->user_data_); - GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, - GRPC_ERROR_REF(err)); - Delete(self); + self->~TrailingMetadataHandler(); } InterceptRecvTrailingMetadataCallback cb_; void* user_data_; - grpc_closure recv_trailing_metadata_ready_; - grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; }; }; From 0f83755c6e676d1e0e67b5f99d06e525bd618944 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 10 May 2019 13:57:01 -0700 Subject: [PATCH 151/676] chttp2 hpack encoder: fast-pathed static md/slice ops --- .../chttp2/transport/hpack_encoder.cc | 105 +++-- .../transport/chttp2/transport/hpack_table.cc | 10 - .../transport/chttp2/transport/hpack_table.h | 11 +- src/core/lib/slice/slice.cc | 3 +- src/core/lib/slice/slice_hash_table.h | 4 +- src/core/lib/slice/slice_intern.cc | 21 +- src/core/lib/slice/slice_internal.h | 31 ++ src/core/lib/slice/slice_weak_hash_table.h | 4 +- src/core/lib/surface/server.cc | 10 +- src/core/lib/transport/metadata.cc | 36 +- src/core/lib/transport/metadata.h | 30 +- src/core/lib/transport/static_metadata.cc | 434 ++++++++++------- src/core/lib/transport/static_metadata.h | 435 +++++++++++------- tools/codegen/core/gen_static_metadata.py | 18 +- 14 files changed, 705 insertions(+), 447 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index d2607e97707..65f9ef4a53a 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -56,7 +56,10 @@ /* don't consider adding anything bigger than this to the hpack table */ #define MAX_DECODER_SPACE_USAGE 512 -static grpc_slice_refcount terminal_slice_refcount; +#define DATA_FRAME_HEADER_SIZE 9 + +static grpc_slice_refcount terminal_slice_refcount( + grpc_slice_refcount::Type::STATIC); static const grpc_slice terminal_slice = { &terminal_slice_refcount, /* refcount */ {{0, nullptr}} /* data.refcounted */ @@ -80,7 +83,8 @@ typedef struct { bool use_true_binary_metadata; } framer_state; -/* fills p (which is expected to be 9 bytes long) with a data frame header */ +/* fills p (which is expected to be DATA_FRAME_HEADER_SIZE bytes long) + * with a data frame header */ static void fill_header(uint8_t* p, uint8_t type, uint32_t id, size_t len, uint8_t flags) { GPR_ASSERT(len < 16777316); @@ -107,15 +111,17 @@ static void finish_frame(framer_state* st, int is_header_boundary, static_cast( (is_last_in_stream ? GRPC_CHTTP2_DATA_FLAG_END_STREAM : 0) | (is_header_boundary ? GRPC_CHTTP2_DATA_FLAG_END_HEADERS : 0))); - st->stats->framing_bytes += 9; + st->stats->framing_bytes += DATA_FRAME_HEADER_SIZE; st->is_first_frame = 0; } /* begin a new frame: reserve off header space, remember how many bytes we'd output before beginning */ static void begin_frame(framer_state* st) { - st->header_idx = - grpc_slice_buffer_add_indexed(st->output, GRPC_SLICE_MALLOC(9)); + grpc_slice reserved; + reserved.refcount = nullptr; + reserved.data.inlined.length = DATA_FRAME_HEADER_SIZE; + st->header_idx = grpc_slice_buffer_add_indexed(st->output, reserved); st->output_length_at_start_of_frame = st->output->length; } @@ -188,8 +194,9 @@ static void evict_entry(grpc_chttp2_hpack_compressor* c) { static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor* c, size_t elem_size) { uint32_t new_index = c->tail_remote_index + c->table_elems + 1; - GPR_ASSERT(elem_size < 65536); + GPR_DEBUG_ASSERT(elem_size < 65536); + // TODO(arjunroy): Re-examine semantics if (elem_size > c->max_table_size) { while (c->table_size > 0) { evict_entry(c); @@ -203,6 +210,7 @@ static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor* c, while (c->table_size + elem_size > c->max_table_size) { evict_entry(c); } + // TODO(arjunroy): Are we conflating size in bytes vs. membership? GPR_ASSERT(c->table_elems < c->max_table_size); c->table_elem_size[new_index % c->cap_table_elems] = static_cast(elem_size); @@ -215,19 +223,19 @@ static uint32_t prepare_space_for_new_elem(grpc_chttp2_hpack_compressor* c, // Add a key to the dynamic table. Both key and value will be added to table at // the decoder. static void add_key_with_index(grpc_chttp2_hpack_compressor* c, - grpc_mdelem elem, uint32_t new_index) { + grpc_mdelem elem, uint32_t new_index, + uint32_t key_hash) { if (new_index == 0) { return; } - uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem)); - /* Store the key into {entries,indices}_keys */ - if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)], - GRPC_MDKEY(elem))) { + if (grpc_slice_static_interned_equal( + c->entries_keys[HASH_FRAGMENT_2(key_hash)], GRPC_MDKEY(elem))) { c->indices_keys[HASH_FRAGMENT_2(key_hash)] = new_index; - } else if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_3(key_hash)], - GRPC_MDKEY(elem))) { + } else if (grpc_slice_static_interned_equal( + c->entries_keys[HASH_FRAGMENT_3(key_hash)], + GRPC_MDKEY(elem))) { c->indices_keys[HASH_FRAGMENT_3(key_hash)] = new_index; } else if (c->entries_keys[HASH_FRAGMENT_2(key_hash)].refcount == &terminal_slice_refcount) { @@ -255,22 +263,20 @@ static void add_key_with_index(grpc_chttp2_hpack_compressor* c, /* add an element to the decoder table */ static void add_elem_with_index(grpc_chttp2_hpack_compressor* c, - grpc_mdelem elem, uint32_t new_index) { + grpc_mdelem elem, uint32_t new_index, + uint32_t elem_hash, uint32_t key_hash) { if (new_index == 0) { return; } - GPR_ASSERT(GRPC_MDELEM_IS_INTERNED(elem)); - - uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem)); - uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem)); - uint32_t elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash); + GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(elem)); /* Store this element into {entries,indices}_elem */ - if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem)) { + if (grpc_mdelem_both_interned_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], + elem)) { /* already there: update with new index */ c->indices_elems[HASH_FRAGMENT_2(elem_hash)] = new_index; - } else if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], - elem)) { + } else if (grpc_mdelem_both_interned_eq( + c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem)) { /* already there (cuckoo): update with new index */ c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; } else if (GRPC_MDISNULL(c->entries_elems[HASH_FRAGMENT_2(elem_hash)])) { @@ -294,19 +300,19 @@ static void add_elem_with_index(grpc_chttp2_hpack_compressor* c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)] = new_index; } - add_key_with_index(c, elem, new_index); + add_key_with_index(c, elem, new_index, key_hash); } static void add_elem(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, - size_t elem_size) { + size_t elem_size, uint32_t elem_hash, uint32_t key_hash) { uint32_t new_index = prepare_space_for_new_elem(c, elem_size); - add_elem_with_index(c, elem, new_index); + add_elem_with_index(c, elem, new_index, elem_hash, key_hash); } static void add_key(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, - size_t elem_size) { + size_t elem_size, uint32_t key_hash) { uint32_t new_index = prepare_space_for_new_elem(c, elem_size); - add_key_with_index(c, elem, new_index); + add_key_with_index(c, elem, new_index, key_hash); } static void emit_indexed(grpc_chttp2_hpack_compressor* c, uint32_t elem_index, @@ -488,27 +494,33 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, return; } - uint32_t key_hash = grpc_slice_hash(GRPC_MDKEY(elem)); uint32_t elem_hash = 0; if (elem_interned) { - uint32_t value_hash = grpc_slice_hash(GRPC_MDVALUE(elem)); - elem_hash = GRPC_MDSTR_KV_HASH(key_hash, value_hash); + if (GRPC_MDELEM_STORAGE(elem) == GRPC_MDELEM_STORAGE_INTERNED) { + elem_hash = + reinterpret_cast(GRPC_MDELEM_DATA(elem)) + ->hash(); + } else { + elem_hash = + reinterpret_cast(GRPC_MDELEM_DATA(elem)) + ->hash(); + } inc_filter(HASH_FRAGMENT_1(elem_hash), &c->filter_elems_sum, c->filter_elems); /* is this elem currently in the decoders table? */ - - if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) && + if (grpc_mdelem_both_interned_eq( + c->entries_elems[HASH_FRAGMENT_2(elem_hash)], elem) && c->indices_elems[HASH_FRAGMENT_2(elem_hash)] > c->tail_remote_index) { /* HIT: complete element (first cuckoo hash) */ emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_2(elem_hash)]), st); return; } - - if (grpc_mdelem_eq(c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) && + if (grpc_mdelem_both_interned_eq( + c->entries_elems[HASH_FRAGMENT_3(elem_hash)], elem) && c->indices_elems[HASH_FRAGMENT_3(elem_hash)] > c->tail_remote_index) { /* HIT: complete element (second cuckoo hash) */ emit_indexed(c, dynidx(c, c->indices_elems[HASH_FRAGMENT_3(elem_hash)]), @@ -527,11 +539,12 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= c->filter_elems_sum / ONE_ON_ADD_PROBABILITY; + uint32_t key_hash = GRPC_MDKEY(elem).refcount->Hash(GRPC_MDKEY(elem)); auto emit_maybe_add = [&should_add_elem, &elem, &st, &c, &indices_key, - &decoder_space_usage] { + &decoder_space_usage, &elem_hash, &key_hash] { if (should_add_elem) { emit_lithdr_incidx(c, dynidx(c, indices_key), elem, st); - add_elem(c, elem, decoder_space_usage); + add_elem(c, elem, decoder_space_usage, elem_hash, key_hash); } else { emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); } @@ -539,8 +552,8 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, /* no hits for the elem... maybe there's a key? */ indices_key = c->indices_keys[HASH_FRAGMENT_2(key_hash)]; - if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_2(key_hash)], - GRPC_MDKEY(elem)) && + if (grpc_slice_static_interned_equal( + c->entries_keys[HASH_FRAGMENT_2(key_hash)], GRPC_MDKEY(elem)) && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ emit_maybe_add(); @@ -548,8 +561,8 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, } indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; - if (grpc_slice_eq(c->entries_keys[HASH_FRAGMENT_3(key_hash)], - GRPC_MDKEY(elem)) && + if (grpc_slice_static_interned_equal( + c->entries_keys[HASH_FRAGMENT_3(key_hash)], GRPC_MDKEY(elem)) && indices_key > c->tail_remote_index) { /* HIT: key (first cuckoo hash) */ emit_maybe_add(); @@ -565,9 +578,9 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, emit_lithdr_noidx_v(c, 0, elem, st); } if (should_add_elem) { - add_elem(c, elem, decoder_space_usage); + add_elem(c, elem, decoder_space_usage, elem_hash, key_hash); } else if (should_add_key) { - add_key(c, elem, decoder_space_usage); + add_key(c, elem, decoder_space_usage, key_hash); } } @@ -692,18 +705,18 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_mdelem md = *extra_headers[i]; - uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(md); + uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(md); if (static_index) { - emit_indexed(c, static_index, &st); + emit_indexed(c, static_cast(static_index), &st); } else { hpack_enc(c, md, &st); } } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md); + uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md); if (static_index) { - emit_indexed(c, static_index, &st); + emit_indexed(c, static_cast(static_index), &st); } else { hpack_enc(c, l->md, &st); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index 16aeb49df4d..f2cbd26f6b8 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -385,13 +385,3 @@ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, return overhead_and_key + value_len; } } - -uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) { - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - uint8_t index = GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table; - if (index < GRPC_CHTTP2_LAST_STATIC_ENTRY) { - return index + 1; // Hpack static metadata element indices start at 1 - } - } - return 0; -} diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h index a0ffc6fab77..38f8bdda6ae 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.h +++ b/src/core/ext/transport/chttp2/transport/hpack_table.h @@ -24,6 +24,7 @@ #include #include "src/core/lib/iomgr/error.h" #include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/static_metadata.h" /* HPACK header table */ @@ -90,7 +91,15 @@ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, /* Returns the static hpack table index that corresponds to /a elem. Returns 0 if /a elem is not statically stored or if it is not in the static hpack table */ -uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md); +inline uintptr_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) { + uintptr_t index = + reinterpret_cast(GRPC_MDELEM_DATA(md)) - + grpc_static_mdelem_table; + if (index < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + return index + 1; // Hpack static metadata element indices start at 1 + } + return 0; +} /* Find a key/value pair in the table... returns the index in the table of the most similar entry, or 0 if the value was not found */ diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 75acb28e99c..3a3edebdc7a 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -68,7 +68,8 @@ void grpc_slice_unref(grpc_slice slice) { /* grpc_slice_from_static_string support structure - a refcount that does nothing */ -static grpc_slice_refcount NoopRefcount; +static grpc_slice_refcount NoopRefcount = + grpc_slice_refcount(grpc_slice_refcount::Type::NOP); size_t grpc_slice_memory_usage(grpc_slice s) { if (s.refcount == nullptr || s.refcount == &NoopRefcount) { diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h index 942830a3e9c..c20eca9db77 100644 --- a/src/core/lib/slice/slice_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -138,7 +138,7 @@ SliceHashTable::~SliceHashTable() { template void SliceHashTable::Add(const grpc_slice& key, T& value) { - const size_t hash = grpc_slice_hash(key); + const size_t hash = grpc_slice_hash_internal(key); for (size_t offset = 0; offset < size_; ++offset) { const size_t idx = (hash + offset) % size_; if (!entries_[idx].is_set) { @@ -156,7 +156,7 @@ void SliceHashTable::Add(const grpc_slice& key, T& value) { template const T* SliceHashTable::Get(const grpc_slice& key) const { - const size_t hash = grpc_slice_hash(key); + const size_t hash = grpc_slice_hash_internal(key); // We cap the number of probes at the max number recorded when // populating the table. for (size_t offset = 0; offset <= max_num_probes_; ++offset) { diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc index 15909d9b96f..81d34ddce25 100644 --- a/src/core/lib/slice/slice_intern.cc +++ b/src/core/lib/slice/slice_intern.cc @@ -128,10 +128,7 @@ int grpc_static_slice_eq(grpc_slice a, grpc_slice b) { return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b); } -uint32_t grpc_slice_hash(grpc_slice s) { - return s.refcount == nullptr ? grpc_slice_default_hash_impl(s) - : s.refcount->Hash(s); -} +uint32_t grpc_slice_hash(grpc_slice s) { return grpc_slice_hash_internal(s); } grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, bool* returned_slice_is_different) { @@ -139,7 +136,7 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, return slice; } - uint32_t hash = grpc_slice_hash(slice); + uint32_t hash = grpc_slice_hash_internal(slice); for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) { static_metadata_hash_ent ent = static_metadata_hash[(hash + i) % GPR_ARRAY_SIZE(static_metadata_hash)]; @@ -154,19 +151,13 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, return slice; } -bool grpc_slice_is_interned(const grpc_slice& slice) { - return (slice.refcount && - (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED || - GRPC_IS_STATIC_METADATA_STRING(slice))); -} - grpc_slice grpc_slice_intern(grpc_slice slice) { GPR_TIMER_SCOPE("grpc_slice_intern", 0); if (GRPC_IS_STATIC_METADATA_STRING(slice)) { return slice; } - uint32_t hash = grpc_slice_hash(slice); + uint32_t hash = grpc_slice_hash_internal(slice); for (uint32_t i = 0; i <= max_static_metadata_hash_probe; i++) { static_metadata_hash_ent ent = @@ -238,7 +229,7 @@ void grpc_slice_intern_init(void) { max_static_metadata_hash_probe = 0; for (size_t i = 0; i < GRPC_STATIC_MDSTR_COUNT; i++) { grpc_static_metadata_hash_values[i] = - grpc_slice_default_hash_impl(grpc_static_slice_table[i]); + grpc_slice_default_hash_internal(grpc_static_slice_table[i]); for (size_t j = 0; j < GPR_ARRAY_SIZE(static_metadata_hash); j++) { size_t slot = (grpc_static_metadata_hash_values[i] + j) % GPR_ARRAY_SIZE(static_metadata_hash); @@ -252,6 +243,10 @@ void grpc_slice_intern_init(void) { } } } + // Handle KV hash for all static mdelems. + for (size_t i = 0; i < GRPC_STATIC_MDELEM_COUNT; ++i) { + grpc_static_mdelem_table[i].HashInit(); + } } void grpc_slice_intern_shutdown(void) { diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index e4aba015315..23a2f6b81bc 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -99,12 +99,15 @@ struct grpc_slice_refcount { enum class Type { STATIC, // Refcount for a static metadata slice. INTERNED, // Refcount for an interned slice. + NOP, // No-Op REGULAR // Refcount for non-static-metadata, non-interned slices. }; typedef void (*DestroyerFn)(void*); grpc_slice_refcount() = default; + explicit grpc_slice_refcount(Type t) : ref_type_(t) {} + explicit grpc_slice_refcount(grpc_slice_refcount* sub) : sub_refcount_(sub) {} // Regular constructor for grpc_slice_refcount. // @@ -200,6 +203,7 @@ inline int grpc_slice_refcount::Eq(const grpc_slice& a, const grpc_slice& b) { return GRPC_STATIC_METADATA_INDEX(a) == GRPC_STATIC_METADATA_INDEX(b); case Type::INTERNED: return a.refcount == b.refcount; + case Type::NOP: case Type::REGULAR: break; } @@ -217,6 +221,7 @@ inline uint32_t grpc_slice_refcount::Hash(const grpc_slice& slice) { case Type::INTERNED: return reinterpret_cast(slice.refcount) ->hash; + case Type::NOP: case Type::REGULAR: break; } @@ -258,6 +263,17 @@ void grpc_slice_buffer_sub_first(grpc_slice_buffer* sb, size_t begin, /* Check if a slice is interned */ bool grpc_slice_is_interned(const grpc_slice& slice); +inline bool grpc_slice_is_interned(const grpc_slice& slice) { + return (slice.refcount && + (slice.refcount->GetType() == grpc_slice_refcount::Type::INTERNED || + slice.refcount->GetType() == grpc_slice_refcount::Type::STATIC)); +} + +inline bool grpc_slice_static_interned_equal(const grpc_slice& a, + const grpc_slice& b) { + GPR_DEBUG_ASSERT(grpc_slice_is_interned(a) && grpc_slice_is_interned(b)); + return a.refcount == b.refcount; +} void grpc_slice_intern_init(void); void grpc_slice_intern_shutdown(void); @@ -271,6 +287,21 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, uint32_t grpc_static_slice_hash(grpc_slice s); int grpc_static_slice_eq(grpc_slice a, grpc_slice b); +inline uint32_t grpc_slice_hash_refcounted(const grpc_slice& s) { + GPR_DEBUG_ASSERT(s.refcount != nullptr); + return s.refcount->Hash(s); +} + +inline uint32_t grpc_slice_default_hash_internal(const grpc_slice& s) { + return gpr_murmur_hash3(GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s), + g_hash_seed); +} + +inline uint32_t grpc_slice_hash_internal(const grpc_slice& s) { + return s.refcount == nullptr ? grpc_slice_default_hash_internal(s) + : grpc_slice_hash_refcounted(s); +} + // Returns the memory used by this slice, not counting the slice structure // itself. This means that inlined and slices from static strings will return // 0. All other slices will return the size of the allocated chars. diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h index 1335c817a39..8c5562bf196 100644 --- a/src/core/lib/slice/slice_weak_hash_table.h +++ b/src/core/lib/slice/slice_weak_hash_table.h @@ -47,7 +47,7 @@ class SliceWeakHashTable : public RefCounted> { /// Add a mapping from \a key to \a value, taking ownership of \a key. This /// operation will always succeed. It may discard older entries. void Add(const grpc_slice& key, T value) { - const size_t idx = grpc_slice_hash(key) % Size; + const size_t idx = grpc_slice_hash_internal(key) % Size; entries_[idx].Set(key, std::move(value)); return; } @@ -55,7 +55,7 @@ class SliceWeakHashTable : public RefCounted> { /// Returns the value from the table associated with / \a key or null if not /// found. const T* Get(const grpc_slice& key) const { - const size_t idx = grpc_slice_hash(key) % Size; + const size_t idx = grpc_slice_hash_internal(key) % Size; const auto& entry = entries_[idx]; return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr; } diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 19f61c548d6..44de0cd42dd 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -625,8 +625,8 @@ static void start_new_rpc(grpc_call_element* elem) { if (chand->registered_methods && calld->path_set && calld->host_set) { /* TODO(ctiller): unify these two searches */ /* check for an exact match with host */ - hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(calld->host), - grpc_slice_hash(calld->path)); + hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash_internal(calld->host), + grpc_slice_hash_internal(calld->path)); for (i = 0; i <= chand->registered_method_max_probes; i++) { rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots]; @@ -644,7 +644,7 @@ static void start_new_rpc(grpc_call_element* elem) { return; } /* check for a wildcard method definition (no host set) */ - hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash(calld->path)); + hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash_internal(calld->path)); for (i = 0; i <= chand->registered_method_max_probes; i++) { rm = &chand->registered_methods[(hash + i) % chand->registered_method_slots]; @@ -1200,8 +1200,8 @@ void grpc_server_setup_transport( has_host = false; } method = grpc_slice_intern(grpc_slice_from_static_string(rm->method)); - hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash(host) : 0, - grpc_slice_hash(method)); + hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash_internal(host) : 0, + grpc_slice_hash_internal(method)); for (probes = 0; chand->registered_methods[(hash + probes) % slots] .server_registered_method != nullptr; probes++) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 4609eb42cdc..2fdecc99d3e 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -43,6 +43,7 @@ using grpc_core::AllocatedMetadata; using grpc_core::InternedMetadata; +using grpc_core::StaticMetadata; using grpc_core::UserData; /* There are two kinds of mdelem and mdstr instances. @@ -100,6 +101,12 @@ void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) +void StaticMetadata::HashInit() { + uint32_t k_hash = grpc_slice_hash_internal(kv_.key); + uint32_t v_hash = grpc_slice_hash_internal(kv_.value); + hash_ = GRPC_MDSTR_KV_HASH(k_hash, v_hash); +} + AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, const grpc_slice& value) : key_(grpc_slice_ref_internal(key)), @@ -133,8 +140,8 @@ InternedMetadata::InternedMetadata(const grpc_slice& key, InternedMetadata* next) : key_(grpc_slice_ref_internal(key)), value_(grpc_slice_ref_internal(value)), - refcnt_(1), hash_(hash), + refcnt_(1), link_(next) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { @@ -223,11 +230,14 @@ void grpc_mdctx_global_shutdown() { } } +#ifndef NDEBUG static int is_mdelem_static(grpc_mdelem e) { - return GRPC_MDELEM_DATA(e) >= &grpc_static_mdelem_table[0] && - GRPC_MDELEM_DATA(e) < + return reinterpret_cast(GRPC_MDELEM_DATA(e)) >= + &grpc_static_mdelem_table[0] && + reinterpret_cast(GRPC_MDELEM_DATA(e)) < &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; } +#endif void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { #ifndef NDEBUG @@ -323,8 +333,8 @@ grpc_mdelem grpc_mdelem_create( } } - uint32_t hash = - GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); + uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash_refcounted(key), + grpc_slice_hash_refcounted(value)); InternedMetadata* md; mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; size_t idx; @@ -391,8 +401,11 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { case GRPC_MDELEM_STORAGE_EXTERNAL: return nullptr; case GRPC_MDELEM_STORAGE_STATIC: - return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - - grpc_static_mdelem_table]; + return reinterpret_cast( + grpc_static_mdelem_user_data + [reinterpret_cast( + GRPC_MDELEM_DATA(md)) - + grpc_static_mdelem_table]); case GRPC_MDELEM_STORAGE_ALLOCATED: { auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); return get_user_data(am->user_data(), destroy_func); @@ -430,15 +443,18 @@ void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), return nullptr; case GRPC_MDELEM_STORAGE_STATIC: destroy_func(data); - return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - - grpc_static_mdelem_table]; + return reinterpret_cast( + grpc_static_mdelem_user_data + [reinterpret_cast( + GRPC_MDELEM_DATA(md)) - + grpc_static_mdelem_table]); case GRPC_MDELEM_STORAGE_ALLOCATED: { auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); return set_user_data(am->user_data(), destroy_func, data); } case GRPC_MDELEM_STORAGE_INTERNED: { auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); - GPR_ASSERT(!is_mdelem_static(md)); + GPR_DEBUG_ASSERT(!is_mdelem_static(md)); return set_user_data(im->user_data(), destroy_func, data); } } diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index f59476ccc21..74c69f97584 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -141,6 +141,16 @@ inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { if (a.payload == b_static.payload) return true; return grpc_slice_eq_static_interned(GRPC_MDVALUE(a), GRPC_MDVALUE(b_static)); } +#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) + +inline bool grpc_mdelem_both_interned_eq(grpc_mdelem a_interned, + grpc_mdelem b_interned) { + GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(a_interned) || + GRPC_MDISNULL(a_interned)); + GPR_DEBUG_ASSERT(GRPC_MDELEM_IS_INTERNED(b_interned) || + GRPC_MDISNULL(b_interned)); + return a_interned.payload == b_interned.payload; +} /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ @@ -169,6 +179,23 @@ struct UserData { grpc_core::Atomic data; }; +class StaticMetadata { + public: + StaticMetadata(const grpc_slice& key, const grpc_slice& value) + : kv_({key, value}), hash_(0) {} + + const grpc_mdelem_data& data() const { return kv_; } + + void HashInit(); + uint32_t hash() { return hash_; } + + private: + grpc_mdelem_data kv_; + + /* private only data */ + uint32_t hash_; +}; + class InternedMetadata { public: struct BucketLink { @@ -227,8 +254,8 @@ class InternedMetadata { grpc_slice value_; /* private only data */ - grpc_core::Atomic refcnt_; uint32_t hash_; + grpc_core::Atomic refcnt_; UserData user_data_; @@ -344,7 +371,6 @@ inline void grpc_mdelem_unref(grpc_mdelem gmd) { } #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) -#define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) /* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */ #define GRPC_MDELEM_LENGTH(e) \ diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 61ee1d46f77..bbf1736b595 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -390,184 +390,270 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) { uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 - ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], + ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]].data(), GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL; } -grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { - {{&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}}, - {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}}, - {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, - {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}}, - {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, - {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}}, - {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}}, - {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}}, - {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}}, - {{&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}}, - {{&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}}, - {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}}, - {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}}, - {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, - {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, - {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, - {{&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, - {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}}, - {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, - {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}}, - {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}}, - {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}}, - {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, - {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, - {{&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}}, - {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}}, - {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, - {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, - {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, +grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + grpc_core::StaticMetadata( + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}), }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index a3f23de0953..800ee04d6f9 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -269,266 +269,353 @@ extern grpc_slice_refcount ((static_slice).refcount - grpc_static_metadata_refcounts))) #define GRPC_STATIC_MDELEM_COUNT 86 -extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; +extern grpc_core::StaticMetadata + grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* ":authority": "" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AUTHORITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_GET \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_POST \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PATH_SLASH \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":scheme": "http" */ -#define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_HTTP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":scheme": "https" */ -#define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_HTTPS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_200 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "204" */ -#define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_204 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "206" */ -#define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_206 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "304" */ -#define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_304 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "400" */ -#define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_400 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_404 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "500" */ -#define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_500 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-charset": "" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "gzip, deflate" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-language": "" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-ranges": "" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept": "" */ -#define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "access-control-allow-origin": "" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "age": "" */ -#define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "allow": "" */ -#define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ALLOW_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "authorization": "" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "cache-control": "" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-disposition": "" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-encoding": "" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-language": "" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-length": "" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-location": "" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-range": "" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-type": "" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "cookie": "" */ -#define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "date": "" */ -#define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_DATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "etag": "" */ -#define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ETAG_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "expect": "" */ -#define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_EXPECT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "expires": "" */ -#define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_EXPIRES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "from": "" */ -#define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_FROM_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "host": "" */ -#define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_HOST_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "if-match": "" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "if-modified-since": "" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "if-none-match": "" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "if-range": "" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "if-unmodified-since": "" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "last-modified": "" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "link": "" */ -#define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LINK_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "location": "" */ -#define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "max-forwards": "" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "proxy-authenticate": "" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "proxy-authorization": "" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "range": "" */ -#define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "referer": "" */ -#define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_REFERER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "refresh": "" */ -#define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_REFRESH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "retry-after": "" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "server": "" */ -#define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SERVER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "set-cookie": "" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SET_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "strict-transport-security": "" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "transfer-encoding": "" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "user-agent": "" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_USER_AGENT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "vary": "" */ -#define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_VARY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "via": "" */ -#define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_VIA_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "www-authenticate": "" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-status": "0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_0 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-status": "1" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_1 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-status": "2" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_2 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_TE_TRAILERS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-type": "application/grpc" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* ":method": "PUT" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_PUT \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-encoding": "identity" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "content-encoding": "gzip" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "lb-token": "" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LB_TOKEN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "lb-cost-bin": "" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "identity,deflate" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "identity,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "deflate,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "identity,deflate,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "identity" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "identity,gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85].data(), \ + GRPC_MDELEM_STORAGE_STATIC)) grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b); typedef enum { @@ -597,14 +684,16 @@ typedef union { : GRPC_BATCH_CALLOUTS_COUNT) extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ - (GRPC_MAKE_MDELEM( \ - &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ + (GRPC_MAKE_MDELEM( \ + &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]] \ + .data(), \ GRPC_MDELEM_STORAGE_STATIC)) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; #define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ - [grpc_static_accept_stream_encoding_metadata[(algs)]], \ + [grpc_static_accept_stream_encoding_metadata[(algs)]] \ + .data(), \ GRPC_MDELEM_STORAGE_STATIC)) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index d66fdc3e835..b534d8dab7e 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -447,14 +447,15 @@ for i, elem in enumerate(all_elems): [len(elem[1])] + [ord(c) for c in elem[1]])) print >> H, '#define GRPC_STATIC_MDELEM_COUNT %d' % len(all_elems) -print >> H, ('extern grpc_mdelem_data ' +print >> H, ('extern grpc_core::StaticMetadata ' 'grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];') print >> H, ('extern uintptr_t ' 'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];') for i, elem in enumerate(all_elems): print >> H, '/* "%s": "%s" */' % elem - print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], ' - 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) + print >> H, ( + '#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d].data(), ' + 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) print >> H print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' @@ -544,13 +545,14 @@ print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intpt print >> C, ' if (a == -1 || b == -1) return GRPC_MDNULL;' print >> C, ' uint32_t k = static_cast(a * %d + b);' % len(all_strs) print >> C, ' uint32_t h = elems_phash(k);' -print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' +print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]].data(), GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' print >> C, '}' print >> C -print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' +print >> C, 'grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' for a, b in all_elems: - print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b))) + print >> C, 'grpc_core::StaticMetadata(%s,%s),' % (slice_def(str_idx(a)), + slice_def(str_idx(b))) print >> C, '};' print >> H, 'typedef enum {' @@ -579,7 +581,7 @@ print >> C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems) print >> C, '};' print >> C -print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' +print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]].data(), GRPC_MDELEM_STORAGE_STATIC))' print >> H print >> H, 'extern const uint8_t grpc_static_accept_stream_encoding_metadata[%d];' % ( @@ -590,7 +592,7 @@ print >> C, '0,%s' % ','.join( '%d' % md_idx(elem) for elem in stream_compression_elems) print >> C, '};' -print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' +print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]].data(), GRPC_MDELEM_STORAGE_STATIC))' print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' From f13abc071cb91c06e90f7121c66f39bae59ec691 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 21 May 2019 19:02:27 -0700 Subject: [PATCH 152/676] Inlined and saved some ops for grpc_is_binary_header. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Various improvements for parsing/encoding: BM_HpackEncoderEncodeDeadline 171ns ± 0% 164ns ± 0% -3.74% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader/0/16384 102ns ± 1% 98ns ± 0% -3.28% (p=0.000 n=20+19) BM_HpackParserParseHeader 177ns ± 1% 165ns ± 1% -6.41% (p=0.000 n=19+18) BM_HpackParserParseHeader, UnrefHeader> 212ns ± 2% 199ns ± 1% -6.28% (p=0.000 n=20+18) --- .../chttp2/transport/hpack_encoder.cc | 18 +++-- .../chttp2/transport/hpack_parser.cc | 21 +++++- .../transport/chttp2/transport/hpack_table.cc | 7 +- .../cronet/transport/cronet_transport.cc | 5 +- src/core/lib/iomgr/error.cc | 6 +- src/core/lib/iomgr/error.h | 12 +++- .../credentials/plugin/plugin_credentials.cc | 2 +- src/core/lib/slice/slice_string_helpers.cc | 2 +- src/core/lib/slice/slice_string_helpers.h | 2 +- src/core/lib/surface/call.cc | 2 +- src/core/lib/surface/channel.cc | 57 +--------------- src/core/lib/surface/channel.h | 66 +++++++++++++++++-- src/core/lib/surface/validate_metadata.cc | 16 +++-- src/core/lib/surface/validate_metadata.h | 15 ++++- 14 files changed, 140 insertions(+), 91 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index d2607e97707..b9871a3633e 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -37,6 +37,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/timeout_encoding.h" @@ -323,9 +324,14 @@ typedef struct { bool insert_null_before_wire_value; } wire_value; +template static wire_value get_wire_value(grpc_mdelem elem, bool true_binary_enabled) { wire_value wire_val; - if (grpc_is_binary_header(GRPC_MDKEY(elem))) { + bool is_bin_hdr = + mdkey_definitely_interned + ? grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem)) + : grpc_is_binary_header_internal(GRPC_MDKEY(elem)); + if (is_bin_hdr) { if (true_binary_enabled) { GRPC_STATS_INC_HPACK_SEND_BINARY(); wire_val.huffman_prefix = 0x00; @@ -363,7 +369,7 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor* c, framer_state* st) { GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX(); uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 2); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); @@ -380,7 +386,7 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor* c, framer_state* st) { GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX(); uint32_t len_pfx = GRPC_CHTTP2_VARINT_LENGTH(key_index, 4); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); size_t len_val = wire_value_length(value); uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); @@ -399,7 +405,7 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor* c, GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V(); GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(); uint32_t len_key = static_cast GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); uint32_t len_val = static_cast(wire_value_length(value)); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); @@ -421,7 +427,7 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor* c, GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V(); GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED(); uint32_t len_key = static_cast GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - wire_value value = get_wire_value(elem, st->use_true_binary_metadata); + wire_value value = get_wire_value(elem, st->use_true_binary_metadata); uint32_t len_val = static_cast(wire_value_length(value)); uint32_t len_key_len = GRPC_CHTTP2_VARINT_LENGTH(len_key, 1); uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); @@ -464,7 +470,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* k = grpc_slice_to_c_string(GRPC_MDKEY(elem)); char* v = nullptr; - if (grpc_is_binary_header(GRPC_MDKEY(elem))) { + if (grpc_is_binary_header_internal(GRPC_MDKEY(elem))) { v = grpc_dump_slice(GRPC_MDVALUE(elem), GPR_DUMP_HEX); } else { v = grpc_slice_to_c_string(GRPC_MDVALUE(elem)); diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 6e422127511..7d5c39e5144 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -35,6 +35,7 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/http2_errors.h" typedef enum { @@ -627,7 +628,7 @@ static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md, if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { char* k = grpc_slice_to_c_string(GRPC_MDKEY(md)); char* v = nullptr; - if (grpc_is_binary_header(GRPC_MDKEY(md))) { + if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) { v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX); } else { v = grpc_slice_to_c_string(GRPC_MDVALUE(md)); @@ -1494,7 +1495,13 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p, /* check if a key represents a binary header or not */ static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) { - return grpc_is_binary_header( + /* We know that either argument here is a reference counter slice. + * 1. If a result of grpc_slice_from_static_buffer, the refcount is set to + * NoopRefcount. + * 2. If it's p->key.data.referenced, then p->key.copied was set to false, + * which occurs in begin_parse_string() - where the refcount is set to + * p->current_slice_refcount, which is not null. */ + return grpc_is_refcounted_slice_binary_header( p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str, p->key.data.copied.length) : p->key.data.referenced); @@ -1511,7 +1518,15 @@ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p, static_cast(p->index)), GRPC_ERROR_INT_SIZE, static_cast(p->table.num_ents)); } - *is = grpc_is_binary_header(GRPC_MDKEY(elem)); + /* We know that GRPC_MDKEY(elem) points to a reference counted slice since: + * 1. elem was a result of grpc_chttp2_hptbl_lookup + * 2. An item in this table is either static (see entries with + * index < GRPC_CHTTP2_LAST_STATIC_ENTRY or added via + * grpc_chttp2_hptbl_add). + * 3. If added via grpc_chttp2_hptbl_add, the entry is either static or + * interned. + * 4. Both static and interned element slices have non-null refcounts. */ + *is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem)); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index 16aeb49df4d..f1cf4acf7dd 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/static_metadata.h" extern grpc_core::TraceFlag grpc_http_trace; @@ -375,9 +376,11 @@ static size_t get_base64_encoded_size(size_t raw_length) { size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, bool use_true_binary_metadata) { - size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); + const uint8_t* key_buf = GRPC_SLICE_START_PTR(GRPC_MDKEY(elem)); + size_t key_len = GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); + size_t overhead_and_key = 32 + key_len; size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem)); - if (grpc_is_binary_header(GRPC_MDKEY(elem))) { + if (grpc_key_is_binary_header(key_buf, key_len)) { return overhead_and_key + (use_true_binary_metadata ? value_len + 1 : get_base64_encoded_size(value_len)); diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 413de807638..3ddda268cfb 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -38,6 +38,7 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/metadata_batch.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/transport_impl.h" @@ -419,7 +420,7 @@ static void convert_cronet_array_to_metadata( grpc_slice key = grpc_slice_intern( grpc_slice_from_static_string(header_array->headers[i].key)); grpc_slice value; - if (grpc_is_binary_header(key)) { + if (grpc_is_refcounted_slice_binary_header(key)) { value = grpc_slice_from_static_string(header_array->headers[i].value); value = grpc_slice_intern(grpc_chttp2_base64_decode_with_length( value, grpc_chttp2_base64_infer_length_after_decode(value))); @@ -746,7 +747,7 @@ static void convert_metadata_to_cronet_headers( curr = curr->next; char* key = grpc_slice_to_c_string(GRPC_MDKEY(mdelem)); char* value; - if (grpc_is_binary_header(GRPC_MDKEY(mdelem))) { + if (grpc_is_binary_header_internal(GRPC_MDKEY(mdelem))) { grpc_slice wire_value = grpc_chttp2_base64_encode(GRPC_MDVALUE(mdelem)); value = grpc_slice_to_c_string(wire_value); grpc_slice_unref_internal(wire_value); diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index f194eb62d48..ebec9dc704a 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -795,9 +795,9 @@ grpc_error* grpc_wsa_error(const char* file, int line, int err, } #endif -bool grpc_log_if_error(const char* what, grpc_error* error, const char* file, - int line) { - if (error == GRPC_ERROR_NONE) return true; +bool grpc_log_error(const char* what, grpc_error* error, const char* file, + int line) { + GPR_DEBUG_ASSERT(error != GRPC_ERROR_NONE); const char* msg = grpc_error_string(error); gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "%s: %s", what, msg); GRPC_ERROR_UNREF(error); diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 7b04888e9ec..0a72e5ca101 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -261,9 +261,15 @@ grpc_error* grpc_wsa_error(const char* file, int line, int err, #define GRPC_WSA_ERROR(err, call_name) \ grpc_wsa_error(__FILE__, __LINE__, err, call_name) -bool grpc_log_if_error(const char* what, grpc_error* error, const char* file, - int line); +bool grpc_log_error(const char* what, grpc_error* error, const char* file, + int line); +inline bool grpc_log_if_error(const char* what, grpc_error* error, + const char* file, int line) { + return error == GRPC_ERROR_NONE ? true + : grpc_log_error(what, error, file, line); +} + #define GRPC_LOG_IF_ERROR(what, error) \ - grpc_log_if_error((what), (error), __FILE__, __LINE__) + (grpc_log_if_error((what), (error), __FILE__, __LINE__)) #endif /* GRPC_CORE_LIB_IOMGR_ERROR_H */ diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 333366d0f0a..92af88aee0b 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -85,7 +85,7 @@ static grpc_error* process_plugin_result( grpc_validate_header_key_is_legal(md[i].key))) { seen_illegal_header = true; break; - } else if (!grpc_is_binary_header(md[i].key) && + } else if (!grpc_is_binary_header_internal(md[i].key) && !GRPC_LOG_IF_ERROR( "validate_metadata_from_plugin", grpc_validate_header_nonbin_value_is_legal(md[i].value))) { diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc index 6af9c33eb56..c2392fd392f 100644 --- a/src/core/lib/slice/slice_string_helpers.cc +++ b/src/core/lib/slice/slice_string_helpers.cc @@ -27,7 +27,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/slice/slice_internal.h" -char* grpc_dump_slice(grpc_slice s, uint32_t flags) { +char* grpc_dump_slice(const grpc_slice& s, uint32_t flags) { return gpr_dump(reinterpret_cast GRPC_SLICE_START_PTR(s), GRPC_SLICE_LENGTH(s), flags); } diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h index 976f72411a8..cb1df658fa5 100644 --- a/src/core/lib/slice/slice_string_helpers.h +++ b/src/core/lib/slice/slice_string_helpers.h @@ -30,7 +30,7 @@ #include "src/core/lib/gpr/string.h" /* Calls gpr_dump on a slice. */ -char* grpc_dump_slice(grpc_slice slice, uint32_t flags); +char* grpc_dump_slice(const grpc_slice& slice, uint32_t flags); /** Split \a str by the separator \a sep. Results are stored in \a dst, which * should be a properly initialized instance. */ diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 254476f47e3..0ae7de29070 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -899,7 +899,7 @@ static int prepare_application_metadata(grpc_call* call, int count, if (!GRPC_LOG_IF_ERROR("validate_metadata", grpc_validate_header_key_is_legal(md->key))) { break; - } else if (!grpc_is_binary_header(md->key) && + } else if (!grpc_is_binary_header_internal(md->key) && !GRPC_LOG_IF_ERROR( "validate_metadata", grpc_validate_header_nonbin_value_is_legal(md->value))) { diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index e47cb4360ea..12869b7780d 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -59,23 +59,6 @@ typedef struct registered_call { struct registered_call* next; } registered_call; -struct grpc_channel { - int is_client; - grpc_compression_options compression_options; - - gpr_atm call_size_estimate; - grpc_resource_user* resource_user; - - gpr_mu registered_call_mu; - registered_call* registered_calls; - - grpc_core::RefCountedPtr channelz_channel; - - char* target; -}; - -#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack*)((c) + 1)) - static void destroy_channel(void* arg, grpc_error* error); grpc_channel* grpc_channel_create_with_builder( @@ -214,11 +197,6 @@ static grpc_channel_args* build_channel_args( return grpc_channel_args_copy_and_add(input_args, new_args, num_new_args); } -grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node( - grpc_channel* channel) { - return channel->channelz_channel.get(); -} - grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* input_args, grpc_channel_stack_type channel_stack_type, @@ -421,21 +399,6 @@ grpc_call* grpc_channel_create_registered_call( return call; } -#ifndef NDEBUG -#define REF_REASON reason -#define REF_ARG , const char* reason -#else -#define REF_REASON "" -#define REF_ARG -#endif -void grpc_channel_internal_ref(grpc_channel* c REF_ARG) { - GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); -} - -void grpc_channel_internal_unref(grpc_channel* c REF_ARG) { - GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON); -} - static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); if (channel->channelz_channel != nullptr) { @@ -475,25 +438,9 @@ void grpc_channel_destroy(grpc_channel* channel) { GRPC_CHANNEL_INTERNAL_UNREF(channel, "channel"); } -grpc_channel_stack* grpc_channel_get_channel_stack(grpc_channel* channel) { - return CHANNEL_STACK_FROM_CHANNEL(channel); -} - -grpc_compression_options grpc_channel_compression_options( - const grpc_channel* channel) { - return channel->compression_options; -} - -grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_channel* channel, int i) { +grpc_mdelem grpc_channel_get_reffed_status_elem_slowpath(grpc_channel* channel, + int i) { char tmp[GPR_LTOA_MIN_BUFSIZE]; - switch (i) { - case 0: - return GRPC_MDELEM_GRPC_STATUS_0; - case 1: - return GRPC_MDELEM_GRPC_STATUS_1; - case 2: - return GRPC_MDELEM_GRPC_STATUS_2; - } gpr_ltoa(i, tmp); return grpc_mdelem_from_slices(GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_copied_string(tmp)); diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index ab00b8e94f7..5d666220745 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -59,22 +59,76 @@ grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node( status_code. The returned elem is owned by the caller. */ -grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_channel* channel, - int status_code); +grpc_mdelem grpc_channel_get_reffed_status_elem_slowpath(grpc_channel* channel, + int status_code); +inline grpc_mdelem grpc_channel_get_reffed_status_elem(grpc_channel* channel, + int status_code) { + switch (status_code) { + case 0: + return GRPC_MDELEM_GRPC_STATUS_0; + case 1: + return GRPC_MDELEM_GRPC_STATUS_1; + case 2: + return GRPC_MDELEM_GRPC_STATUS_2; + } + return grpc_channel_get_reffed_status_elem_slowpath(channel, status_code); +} size_t grpc_channel_get_call_size_estimate(grpc_channel* channel); void grpc_channel_update_call_size_estimate(grpc_channel* channel, size_t size); +struct registered_call; +struct grpc_channel { + int is_client; + grpc_compression_options compression_options; + + gpr_atm call_size_estimate; + grpc_resource_user* resource_user; + + gpr_mu registered_call_mu; + registered_call* registered_calls; + + grpc_core::RefCountedPtr channelz_channel; + + char* target; +}; +#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack*)((c) + 1)) + +inline grpc_compression_options grpc_channel_compression_options( + const grpc_channel* channel) { + return channel->compression_options; +} + +inline grpc_channel_stack* grpc_channel_get_channel_stack( + grpc_channel* channel) { + return CHANNEL_STACK_FROM_CHANNEL(channel); +} + +inline grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node( + grpc_channel* channel) { + return channel->channelz_channel.get(); +} + #ifndef NDEBUG -void grpc_channel_internal_ref(grpc_channel* channel, const char* reason); -void grpc_channel_internal_unref(grpc_channel* channel, const char* reason); +inline void grpc_channel_internal_ref(grpc_channel* channel, + const char* reason) { + GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(channel), reason); +} +inline void grpc_channel_internal_unref(grpc_channel* channel, + const char* reason) { + GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CHANNEL(channel), reason); +} #define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ grpc_channel_internal_ref(channel, reason) #define GRPC_CHANNEL_INTERNAL_UNREF(channel, reason) \ grpc_channel_internal_unref(channel, reason) #else -void grpc_channel_internal_ref(grpc_channel* channel); -void grpc_channel_internal_unref(grpc_channel* channel); +inline void grpc_channel_internal_ref(grpc_channel* channel) { + GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(channel), "unused"); +} +inline void grpc_channel_internal_unref(grpc_channel* channel) { + GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CHANNEL(channel), "unused"); +} #define GRPC_CHANNEL_INTERNAL_REF(channel, reason) \ grpc_channel_internal_ref(channel) #define GRPC_CHANNEL_INTERNAL_UNREF(channel, reason) \ diff --git a/src/core/lib/surface/validate_metadata.cc b/src/core/lib/surface/validate_metadata.cc index 2dd18f3dd3f..a92ab823a38 100644 --- a/src/core/lib/surface/validate_metadata.cc +++ b/src/core/lib/surface/validate_metadata.cc @@ -29,7 +29,8 @@ #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/surface/validate_metadata.h" -static grpc_error* conforms_to(grpc_slice slice, const uint8_t* legal_bits, +static grpc_error* conforms_to(const grpc_slice& slice, + const uint8_t* legal_bits, const char* err_desc) { const uint8_t* p = GRPC_SLICE_START_PTR(slice); const uint8_t* e = GRPC_SLICE_END_PTR(slice); @@ -57,7 +58,7 @@ static int error2int(grpc_error* error) { return r; } -grpc_error* grpc_validate_header_key_is_legal(grpc_slice slice) { +grpc_error* grpc_validate_header_key_is_legal(const grpc_slice& slice) { static const uint8_t legal_header_bits[256 / 8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0x00, 0x00, 0x00, 0x80, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -77,7 +78,8 @@ int grpc_header_key_is_legal(grpc_slice slice) { return error2int(grpc_validate_header_key_is_legal(slice)); } -grpc_error* grpc_validate_header_nonbin_value_is_legal(grpc_slice slice) { +grpc_error* grpc_validate_header_nonbin_value_is_legal( + const grpc_slice& slice) { static const uint8_t legal_header_bits[256 / 8] = { 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -89,7 +91,11 @@ int grpc_header_nonbin_value_is_legal(grpc_slice slice) { return error2int(grpc_validate_header_nonbin_value_is_legal(slice)); } +int grpc_is_binary_header_internal(const grpc_slice& slice) { + return grpc_key_is_binary_header(GRPC_SLICE_START_PTR(slice), + GRPC_SLICE_LENGTH(slice)); +} + int grpc_is_binary_header(grpc_slice slice) { - if (GRPC_SLICE_LENGTH(slice) < 5) return 0; - return 0 == memcmp(GRPC_SLICE_END_PTR(slice) - 4, "-bin", 4); + return grpc_is_binary_header_internal(slice); } diff --git a/src/core/lib/surface/validate_metadata.h b/src/core/lib/surface/validate_metadata.h index e87fb7beedc..db3be684c11 100644 --- a/src/core/lib/surface/validate_metadata.h +++ b/src/core/lib/surface/validate_metadata.h @@ -24,7 +24,18 @@ #include #include "src/core/lib/iomgr/error.h" -grpc_error* grpc_validate_header_key_is_legal(grpc_slice slice); -grpc_error* grpc_validate_header_nonbin_value_is_legal(grpc_slice slice); +grpc_error* grpc_validate_header_key_is_legal(const grpc_slice& slice); +grpc_error* grpc_validate_header_nonbin_value_is_legal(const grpc_slice& slice); + +int grpc_is_binary_header_internal(const grpc_slice& slice); +inline int grpc_key_is_binary_header(const uint8_t* buf, size_t length) { + if (length < 5) return 0; + return 0 == memcmp(buf + length - 4, "-bin", 4); +} +inline int grpc_is_refcounted_slice_binary_header(const grpc_slice& slice) { + GPR_DEBUG_ASSERT(slice.refcount != nullptr); + return grpc_key_is_binary_header(slice.data.refcounted.bytes, + slice.data.refcounted.length); +} #endif /* GRPC_CORE_LIB_SURFACE_VALIDATE_METADATA_H */ From bd2756e482b90df42bc3f60105cb06841331aad9 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 28 May 2019 15:39:53 -0700 Subject: [PATCH 153/676] Fix format --- test/cpp/util/test_credentials_provider.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 41779327cb9..fd796372c8c 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -119,8 +119,8 @@ class DefaultCredentialsProvider : public CredentialsProvider { SslServerCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = ""; if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { - SslServerCredentialsOptions::PemKeyCertPair pkcp = {custom_server_key_, - custom_server_cert_}; + SslServerCredentialsOptions::PemKeyCertPair pkcp = { + custom_server_key_, custom_server_cert_}; ssl_opts.pem_key_cert_pairs.push_back(pkcp); } else { SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, From 740c931e239a6a823e0fb86ced095f930fae9730 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 28 May 2019 16:25:01 -0700 Subject: [PATCH 154/676] Adjust the order of IOMgr initialization, so as to set up a customized timer correctly. Also, change the comment of grpc_timer::heap_index. --- src/core/lib/iomgr/iomgr.cc | 2 +- src/core/lib/iomgr/timer.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index b86aa6f2d76..b09d19fa759 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -57,10 +57,10 @@ void grpc_iomgr_init() { gpr_mu_init(&g_mu); gpr_cv_init(&g_rcv); grpc_core::Executor::InitAll(); - grpc_timer_list_init(); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = (char*)"root"; grpc_iomgr_platform_init(); + grpc_timer_list_init(); grpc_core::grpc_errqueue_init(); } diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h index 17e933b8658..11da1496523 100644 --- a/src/core/lib/iomgr/timer.h +++ b/src/core/lib/iomgr/timer.h @@ -29,7 +29,8 @@ typedef struct grpc_timer { grpc_millis deadline; - uint32_t heap_index; /* INVALID_HEAP_INDEX if not in heap */ + // Uninitialized if not using heap, or INVALID_HEAP_INDEX if not in heap. + uint32_t heap_index; bool pending; struct grpc_timer* next; struct grpc_timer* prev; From 7ec666948126320145a33ccb902b90f037301410 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 May 2019 16:56:25 -0700 Subject: [PATCH 155/676] address comments --- src/objective-c/GRPCClient/GRPCCall.m | 29 +------ src/objective-c/GRPCClient/GRPCInterceptor.h | 2 +- src/objective-c/GRPCClient/GRPCInterceptor.m | 52 +++++------- .../project.pbxproj | 9 +- .../InterceptorSample/CacheInterceptor.m | 4 + .../tests/Tests.xcodeproj/project.pbxproj | 84 +++++++++---------- 6 files changed, 67 insertions(+), 113 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 617208b8079..cee86d6704e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -152,7 +152,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; } else { for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { GRPCInterceptorManager *manager = - [[GRPCInterceptorManager alloc] initWithNextInerceptor:nextInterceptor]; + [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; GRPCInterceptor *interceptor = [interceptorFactories[i] createInterceptorWithManager:manager]; NSAssert(interceptor != nil, @"Failed to create interceptor"); @@ -244,33 +244,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } -- (void)issueDidWriteData { - @synchronized(self) { - if (_callOptions.flowControlEnabled && [_handler respondsToSelector:@selector(didWriteData)]) { - dispatch_async(_dispatchQueue, ^{ - id copiedHandler = nil; - @synchronized(self) { - copiedHandler = self->_handler; - }; - [copiedHandler didWriteData]; - }); - } - } -} - -- (void)receiveNextMessages:(NSUInteger)numberOfMessages { - // branching based on _callOptions.flowControlEnabled is handled inside _call - GRPCCall *copiedCall = nil; - @synchronized(self) { - copiedCall = _call; - if (copiedCall == nil) { - _pendingReceiveNextMessages += numberOfMessages; - return; - } - } - [copiedCall receiveNextMessages:numberOfMessages]; -} - @end // The following methods of a C gRPC call object aren't reentrant, and thus diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h index 931f6e4aa5a..aa1c4d18565 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.h +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -177,7 +177,7 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype) new NS_UNAVAILABLE; -- (nullable instancetype)initWithNextInerceptor:(id)nextInterceptor +- (nullable instancetype)initWithNextInterceptor:(id)nextInterceptor NS_DESIGNATED_INITIALIZER; /** Set the previous interceptor in the chain. Can only be set once. */ diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.m b/src/objective-c/GRPCClient/GRPCInterceptor.m index 1c1f0b53114..6be27d74c11 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.m +++ b/src/objective-c/GRPCClient/GRPCInterceptor.m @@ -25,7 +25,7 @@ id _previousInterceptor; } -- (instancetype)initWithNextInerceptor:(id)nextInterceptor { +- (instancetype)initWithNextInterceptor:(id)nextInterceptor { if ((self = [super init])) { _nextInterceptor = nextInterceptor; } @@ -44,49 +44,39 @@ - (void)startNextInterceptorWithRequest:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { - if ([_nextInterceptor respondsToSelector:@selector(startWithRequestOptions:callOptions:)]) { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; - }); - } + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; + }); } - (void)writeNextInterceptorWithData:(id)data { - if ([_nextInterceptor respondsToSelector:@selector(writeData:)]) { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor writeData:data]; - }); - } + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor writeData:data]; + }); } - (void)finishNextInterceptor { - if ([_nextInterceptor respondsToSelector:@selector(finish)]) { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor finish]; - }); - } + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor finish]; + }); } - (void)cancelNextInterceptor { - if ([_nextInterceptor respondsToSelector:@selector(cancel)]) { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor cancel]; - }); - } + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor cancel]; + }); } /** Notify the next interceptor in the chain to receive more messages */ - (void)receiveNextInterceptorMessages:(NSUInteger)numberOfMessages { - if ([_nextInterceptor respondsToSelector:@selector(receiveNextMessages:)]) { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor receiveNextMessages:numberOfMessages]; - }); - } + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor receiveNextMessages:numberOfMessages]; + }); } // Methods to forward GRPCResponseHandler callbacks to the previous object diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj b/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj index e72ef6edc61..8b8811d4c62 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample.xcodeproj/project.pbxproj @@ -174,16 +174,11 @@ files = ( ); inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + "${PODS_ROOT}/Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + "${PODS_ROOT}/Target Support Files/Pods-InterceptorSample/Pods-InterceptorSample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m index 082bd303dec..4e0cf2c90ed 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m @@ -145,6 +145,10 @@ ResponseCacheEntry *response = nil; @synchronized(self) { response = [_cache objectForKey:request]; + if ([response.deadline timeIntervalSinceNow] < 0) { + [_cache removeObjectForKey:request]; + response = nil; + } } return response; } diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 27a617c83b4..de5461f1d2f 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -1360,7 +1360,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1369,7 +1369,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-resources.sh\"\n"; showEnvVarsInLog = 0; }; 1EAF0CBDBFAB18D4DA64535D /* [CP] Copy Pods Resources */ = { @@ -1378,7 +1378,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1387,7 +1387,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ChannelTests/Pods-ChannelTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; 252A376345E38FD452A89C3D /* [CP] Check Pods Manifest.lock */ = { @@ -1432,7 +1432,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -1441,7 +1441,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 452FDC3918FEC23ECAFD31EC /* [CP] Copy Pods Resources */ = { @@ -1449,21 +1449,17 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-macOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MacTests/Pods-MacTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; 483CDBBAEAEFCB530ADDDDD5 /* [CP] Check Pods Manifest.lock */ = { @@ -1508,7 +1504,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1517,7 +1513,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream-resources.sh\"\n"; showEnvVarsInLog = 0; }; 5C20DCCB71C3991E6FE78C22 /* [CP] Check Pods Manifest.lock */ = { @@ -1544,7 +1540,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1553,7 +1549,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; 6BA6D00B1816306453BF82D4 /* [CP] Copy Pods Resources */ = { @@ -1562,7 +1558,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1571,7 +1567,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsCallOptions/Pods-InteropTestsCallOptions-resources.sh\"\n"; showEnvVarsInLog = 0; }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { @@ -1616,7 +1612,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1625,7 +1621,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext-resources.sh\"\n"; showEnvVarsInLog = 0; }; 8C1ED025E07C4D457C355336 /* [CP] Check Pods Manifest.lock */ = { @@ -1652,7 +1648,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -1661,7 +1657,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsMultipleChannels/Pods-InteropTestsMultipleChannels-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 914ADDD7106BA9BB8A7E569F /* [CP] Check Pods Manifest.lock */ = { @@ -1688,7 +1684,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1697,7 +1693,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh\"\n"; showEnvVarsInLog = 0; }; 9AD0B5E94F2AA5962EA6AA36 /* [CP] Copy Pods Resources */ = { @@ -1706,7 +1702,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1715,7 +1711,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */ = { @@ -1724,7 +1720,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1733,7 +1729,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream-resources.sh\"\n"; showEnvVarsInLog = 0; }; A441F71824DCB9D0CA297748 /* [CP] Copy Pods Resources */ = { @@ -1742,7 +1738,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1751,7 +1747,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AllTests/Pods-AllTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; A686B9967BB4CB81B1CBF8F8 /* [CP] Embed Pods Frameworks */ = { @@ -1760,7 +1756,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -1769,7 +1765,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CronetUnitTests/Pods-CronetUnitTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; B2986CEEE8CDD4901C97598B /* [CP] Check Pods Manifest.lock */ = { @@ -1813,21 +1809,17 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-APIv2Tests/Pods-APIv2Tests-resources.sh\"\n"; showEnvVarsInLog = 0; }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { @@ -1836,7 +1828,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1845,7 +1837,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote-resources.sh\"\n"; showEnvVarsInLog = 0; }; C977426A8727267BBAC7D48E /* [CP] Copy Pods Resources */ = { @@ -1854,7 +1846,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1863,7 +1855,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */ = { @@ -1872,7 +1864,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh", + "${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh", "${PODS_CONFIGURATION_BUILD_DIR}/gRPC-iOS/gRPCCertificates.bundle", ); name = "[CP] Copy Pods Resources"; @@ -1881,7 +1873,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n"; showEnvVarsInLog = 0; }; E5B20F69559C6AE299DFEA7C /* [CP] Check Pods Manifest.lock */ = { @@ -1912,7 +1904,7 @@ files = ( ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh", + "${PODS_ROOT}/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh", "${PODS_ROOT}/CronetFramework/Cronet.framework", ); name = "[CP] Embed Pods Frameworks"; @@ -1921,7 +1913,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; EDDD3FA856BCA3443ED36D1E /* [CP] Check Pods Manifest.lock */ = { From 7c8d6f63756ff0871cd8e251973375078f151f4f Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 28 May 2019 17:13:41 -0700 Subject: [PATCH 156/676] s/uintptr_t/intptr_t as requested --- src/core/lib/surface/call.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 271b3ddd560..e00ac1810de 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -99,7 +99,7 @@ struct batch_control { } completion_data; grpc_closure start_batch; grpc_closure finish_batch; - grpc_core::Atomic steps_to_complete; + grpc_core::Atomic steps_to_complete; gpr_atm batch_error = reinterpret_cast(GRPC_ERROR_NONE); void set_num_steps_to_complete(uintptr_t steps) { steps_to_complete.Store(steps, grpc_core::MemoryOrder::RELEASE); From 14c55dea4ab8a7a24003f0497c6b166079096be1 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 14 May 2019 16:19:07 -0700 Subject: [PATCH 157/676] Inline more of md_unref for interned metadata. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the common case, unref() for interned metadata was performing some unnecessary branches. This patch reduces the instruction count from about 19 to 12 in the case where an unref() occured but it wasn't the last reference. This has various speedups for chttp2_hpack, metadata and fullstack pingpong benchmarks. As a tradeoff, static/external metadata unref regresses slightly (fraction of a nanosecond increase in CPU time) while interned improves (roughly 5 nanoseconds reduction in CPU time). Examples: Fullstack: BM_UnaryPingPong/8/8 [polls/iter:0 ] 7.12µs ± 4% 6.91µs ± 3% -3.00% (p=0.000 n=20+19) BM_UnaryPingPong/0/32768 [polls/iter:3.0001 ] 35.3µs ± 2% 34.9µs ± 0% -1.15% (p=0.048 n=8+4) BM_UnaryPingPong/32768/32768 [polls/iter:3.00014 ] 49.6µs ± 1% 49.0µs ± 1% -1.15% (p=0.017 n=7+3) HpackParser: BM_HpackEncoderInitDestroy 274ns ± 0% 254ns ± 0% -7.12% (p=0.000 n=19+19) BM_HpackParserParseHeader 173ns ± 0% 140ns ± 0% -19.04% (p=0.000 n=18+16) BM_HpackParserParseHeader 751ns ± 1% 702ns ± 2% -6.50% (p=0.000 n=20+20) BM_HpackParserParseHeader 50.6ns ± 0% 46.9ns ± 0% -7.29% (p=0.000 n=14+19) BM_HpackParserParseHeader 486ns ± 1% 455ns ± 0% -6.42% (p=0.000 n=20+19) BM_HpackParserParseHeader 1.17µs ± 1% 1.12µs ± 1% -4.18% (p=0.000 n=18+20) BM_HpackParserParseHeader 163ns ± 1% 155ns ± 0% -4.52% (p=0.000 n=18+17) Metadata: BM_MetadataFromInternedKeyWithBackingStore 7.32ns ± 1% 6.67ns ± 0% -8.89% (p=0.000 n=20+17) BM_MetadataFromStaticMetadataStringsNotIndexed 77.4ns ± 2% 79.6ns ± 0% +2.86% (p=0.000 n=18+19) BM_MetadataRefUnrefExternal 1.74ns ± 0% 1.79ns ± 0% +2.65% (p=0.000 n=20+19) BM_MetadataRefUnrefInterned 18.5ns ± 0% 13.3ns ± 0% -28.00% (p=0.000 n=17+17) BM_MetadataRefUnrefAllocated 18.5ns ± 0% 13.3ns ± 0% -28.00% (p=0.000 n=17+18) --- src/core/lib/transport/metadata.cc | 48 ++++++---- src/core/lib/transport/metadata.h | 135 +++++++++++++---------------- 2 files changed, 93 insertions(+), 90 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 2fdecc99d3e..1523ced16d8 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -109,13 +109,12 @@ void StaticMetadata::HashInit() { AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, const grpc_slice& value) - : key_(grpc_slice_ref_internal(key)), - value_(grpc_slice_ref_internal(value)), - refcnt_(1) { + : RefcountedMdBase(grpc_slice_ref_internal(key), + grpc_slice_ref_internal(value)) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(key_); - char* value_str = grpc_slice_to_c_string(value_); + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", this, RefValue(), key_str, value_str); gpr_free(key_str); @@ -125,8 +124,8 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, } AllocatedMetadata::~AllocatedMetadata() { - grpc_slice_unref_internal(key_); - grpc_slice_unref_internal(value_); + grpc_slice_unref_internal(key()); + grpc_slice_unref_internal(value()); void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); if (user_data) { destroy_user_data_func destroy_user_data = @@ -138,15 +137,13 @@ AllocatedMetadata::~AllocatedMetadata() { InternedMetadata::InternedMetadata(const grpc_slice& key, const grpc_slice& value, uint32_t hash, InternedMetadata* next) - : key_(grpc_slice_ref_internal(key)), - value_(grpc_slice_ref_internal(value)), - hash_(hash), - refcnt_(1), + : RefcountedMdBase(grpc_slice_ref_internal(key), + grpc_slice_ref_internal(value), hash), link_(next) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(key_); - char* value_str = grpc_slice_to_c_string(value_); + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", this, RefValue(), key_str, value_str); gpr_free(key_str); @@ -156,8 +153,8 @@ InternedMetadata::InternedMetadata(const grpc_slice& key, } InternedMetadata::~InternedMetadata() { - grpc_slice_unref_internal(key_); - grpc_slice_unref_internal(value_); + grpc_slice_unref_internal(key()); + grpc_slice_unref_internal(value()); void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); if (user_data) { destroy_user_data_func destroy_user_data = @@ -242,8 +239,8 @@ static int is_mdelem_static(grpc_mdelem e) { void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(key_); - char* value_str = grpc_slice_to_c_string(value_); + char* key_str = grpc_slice_to_c_string(key()); + char* value_str = grpc_slice_to_c_string(value()); intptr_t value = RefValue(); gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG, "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this, value, @@ -498,3 +495,20 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { } } } + +void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr, + uint32_t hash DEBUG_ARGS) { + switch (storage) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: { + note_disposed_interned_metadata(hash); + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + grpc_core::Delete(reinterpret_cast(ptr)); + break; + } + } +} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 74c69f97584..3cef031031d 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -80,17 +80,22 @@ typedef struct grpc_mdelem_data { this bit set in their integer value */ #define GRPC_MDELEM_STORAGE_INTERNED_BIT 1 +/* External and static storage metadata has no refcount to ref/unref. Allocated + * and interned metadata do have a refcount. Metadata ref and unref methods use + * a switch statement on this enum to determine which behaviour to execute. + * Keeping the no-ref cases together and the ref-cases together leads to + * slightly better code generation (9 inlined instructions rather than 10). */ typedef enum { /* memory pointed to by grpc_mdelem::payload is owned by an external system */ GRPC_MDELEM_STORAGE_EXTERNAL = 0, - /* memory pointed to by grpc_mdelem::payload is interned by the metadata - system */ - GRPC_MDELEM_STORAGE_INTERNED = GRPC_MDELEM_STORAGE_INTERNED_BIT, + /* memory is in the static metadata table */ + GRPC_MDELEM_STORAGE_STATIC = GRPC_MDELEM_STORAGE_INTERNED_BIT, /* memory pointed to by grpc_mdelem::payload is allocated by the metadata system */ GRPC_MDELEM_STORAGE_ALLOCATED = 2, - /* memory is in the static metadata table */ - GRPC_MDELEM_STORAGE_STATIC = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT, + /* memory pointed to by grpc_mdelem::payload is interned by the metadata + system */ + GRPC_MDELEM_STORAGE_INTERNED = 2 | GRPC_MDELEM_STORAGE_INTERNED_BIT, } grpc_mdelem_data_storage; struct grpc_mdelem { @@ -196,17 +201,17 @@ class StaticMetadata { uint32_t hash_; }; -class InternedMetadata { +class RefcountedMdBase { public: - struct BucketLink { - explicit BucketLink(InternedMetadata* md) : next(md) {} - - InternedMetadata* next = nullptr; - }; + RefcountedMdBase(const grpc_slice& key, const grpc_slice& value) + : key_(key), value_(value), refcnt_(1) {} + RefcountedMdBase(const grpc_slice& key, const grpc_slice& value, + uint32_t hash) + : key_(key), value_(value), refcnt_(1), hash_(hash) {} - InternedMetadata(const grpc_slice& key, const grpc_slice& value, - uint32_t hash, InternedMetadata* next); - ~InternedMetadata(); + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + uint32_t hash() { return hash_; } #ifndef NDEBUG void Ref(const char* file, int line) { @@ -218,92 +223,65 @@ class InternedMetadata { grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); return Unref(); } -#else - // We define a naked Ref() in the else-clause to make sure we don't - // inadvertently skip the assert on debug builds. +#endif void Ref() { /* we can assume the ref count is >= 1 as the application is calling this function - meaning that no adjustment to mdtab_free is necessary, simplifying the logic here to be just an atomic increment */ refcnt_.FetchAdd(1, MemoryOrder::RELAXED); } -#endif // ifndef NDEBUG bool Unref() { const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } - void RefWithShardLocked(mdtab_shard* shard); - const grpc_slice& key() const { return key_; } - const grpc_slice& value() const { return value_; } - UserData* user_data() { return &user_data_; } - uint32_t hash() { return hash_; } - InternedMetadata* bucket_next() { return link_.next; } - void set_bucket_next(InternedMetadata* md) { link_.next = md; } - - static size_t CleanupLinkedMetadata(BucketLink* head); - - private: + protected: + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; } - intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + private: /* must be byte compatible with grpc_mdelem_data */ grpc_slice key_; grpc_slice value_; - - /* private only data */ - uint32_t hash_; grpc_core::Atomic refcnt_; + uint32_t hash_ = 0; +}; - UserData user_data_; +class InternedMetadata : public RefcountedMdBase { + public: + struct BucketLink { + explicit BucketLink(InternedMetadata* md) : next(md) {} + + InternedMetadata* next = nullptr; + }; + + InternedMetadata(const grpc_slice& key, const grpc_slice& value, + uint32_t hash, InternedMetadata* next); + ~InternedMetadata(); + + void RefWithShardLocked(mdtab_shard* shard); + UserData* user_data() { return &user_data_; } + InternedMetadata* bucket_next() { return link_.next; } + void set_bucket_next(InternedMetadata* md) { link_.next = md; } + + static size_t CleanupLinkedMetadata(BucketLink* head); + private: + UserData user_data_; BucketLink link_; }; /* Shadow structure for grpc_mdelem_data for allocated elements */ -class AllocatedMetadata { +class AllocatedMetadata : public RefcountedMdBase { public: AllocatedMetadata(const grpc_slice& key, const grpc_slice& value); ~AllocatedMetadata(); - const grpc_slice& key() const { return key_; } - const grpc_slice& value() const { return value_; } UserData* user_data() { return &user_data_; } -#ifndef NDEBUG - void Ref(const char* file, int line) { - grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); - Ref(); - } - bool Unref(const char* file, int line) { - grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); - return Unref(); - } -#endif // ifndef NDEBUG - void Ref() { - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - refcnt_.FetchAdd(1, MemoryOrder::RELAXED); - } - bool Unref() { - const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); - GPR_DEBUG_ASSERT(prior > 0); - return prior == 1; - } - private: - intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } - - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key_; - grpc_slice value_; - - /* private only data */ - grpc_core::Atomic refcnt_; - UserData user_data_; }; @@ -348,24 +326,35 @@ inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd) { #ifndef NDEBUG #define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) -void grpc_mdelem_do_unref(grpc_mdelem gmd, const char* file, int line); +void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr, + uint32_t hash, const char* file, int line); inline void grpc_mdelem_unref(grpc_mdelem gmd, const char* file, int line) { #else #define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) -void grpc_mdelem_do_unref(grpc_mdelem gmd); +void grpc_mdelem_on_final_unref(grpc_mdelem_data_storage storage, void* ptr, + uint32_t hash); inline void grpc_mdelem_unref(grpc_mdelem gmd) { #endif - switch (GRPC_MDELEM_STORAGE(gmd)) { + const grpc_mdelem_data_storage storage = GRPC_MDELEM_STORAGE(gmd); + switch (storage) { case GRPC_MDELEM_STORAGE_EXTERNAL: case GRPC_MDELEM_STORAGE_STATIC: return; case GRPC_MDELEM_STORAGE_INTERNED: case GRPC_MDELEM_STORAGE_ALLOCATED: + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); + /* once the refcount hits zero, some other thread can come along and + free an interned md at any time: it's unsafe from this point on to + access it so we read the hash now. */ + uint32_t hash = md->hash(); + if (GPR_UNLIKELY(md->Unref())) { #ifndef NDEBUG - grpc_mdelem_do_unref(gmd, file, line); + grpc_mdelem_on_final_unref(storage, md, hash, file, line); #else - grpc_mdelem_do_unref(gmd); + grpc_mdelem_on_final_unref(storage, md, hash); #endif + } return; } } From 2cb1892c77529bfbcf5560ec222a239330ed3aa0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 28 May 2019 20:59:00 -0700 Subject: [PATCH 158/676] address comments --- src/objective-c/GRPCClient/GRPCCall.m | 2 - src/objective-c/GRPCClient/GRPCInterceptor.h | 2 +- src/objective-c/GRPCClient/GRPCInterceptor.m | 4 +- .../InterceptorSample/CacheInterceptor.m | 29 +++-- src/objective-c/tests/InteropTests.m | 110 +++++++++--------- 5 files changed, 73 insertions(+), 74 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index cee86d6704e..d05f90f7dd2 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -68,8 +68,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; callOptions:(GRPCCallOptions *)callOptions writeDone:(void (^)(void))writeDone; -- (void)receiveNextMessages:(NSUInteger)numberOfMessages; - @end @implementation GRPCRequestOptions diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h index aa1c4d18565..4b7bcdbff40 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.h +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -210,7 +210,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)forwardPreviousInterceptorWithInitialMetadata:(nullable NSDictionary *)initialMetadata; /** Forward a received message to the previous interceptor in the chain */ -- (void)forwardPreviousIntercetporWithData:(nullable id)data; +- (void)forwardPreviousInterceptorWithData:(nullable id)data; /** Forward call close and trailing metadata to the previous interceptor in the chain */ - (void)forwardPreviousInterceptorCloseWithTrailingMetadata: diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.m b/src/objective-c/GRPCClient/GRPCInterceptor.m index 6be27d74c11..bf043fcd1f5 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.m +++ b/src/objective-c/GRPCClient/GRPCInterceptor.m @@ -92,7 +92,7 @@ } /** Forward a received message to the previous interceptor in the chain */ -- (void)forwardPreviousIntercetporWithData:(id)data { +- (void)forwardPreviousInterceptorWithData:(id)data { if ([_previousInterceptor respondsToSelector:@selector(didReceiveData:)]) { id copiedPreviousInterceptor = _previousInterceptor; dispatch_async(copiedPreviousInterceptor.dispatchQueue, ^{ @@ -194,7 +194,7 @@ } - (void)didReceiveData:(id)data { - [_manager forwardPreviousIntercetporWithData:data]; + [_manager forwardPreviousInterceptorWithData:data]; } - (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { diff --git a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m index 4e0cf2c90ed..c8e584d37bc 100644 --- a/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m +++ b/src/objective-c/examples/InterceptorSample/InterceptorSample/CacheInterceptor.m @@ -167,7 +167,8 @@ dispatch_queue_t _dispatchQueue; BOOL _cacheable; - BOOL _messageSeen; + BOOL _writeMessageSeen; + BOOL _readMessageSeen; GRPCCallOptions *_callOptions; GRPCRequestOptions *_requestOptions; id _requestMessage; @@ -193,7 +194,8 @@ _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); _cacheable = YES; - _messageSeen = NO; + _writeMessageSeen = NO; + _readMessageSeen = NO; _request = nil; _response = nil; } @@ -202,9 +204,7 @@ - (void)startWithRequestOptions:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { - NSLog(@"start"); if (requestOptions.safety != GRPCCallSafetyCacheableRequest) { - NSLog(@"no cache"); _cacheable = NO; [_manager startNextInterceptorWithRequest:requestOptions callOptions:callOptions]; } else { @@ -214,21 +214,19 @@ } - (void)writeData:(id)data { - NSLog(@"writeData"); if (!_cacheable) { [_manager writeNextInterceptorWithData:data]; } else { - NSAssert(!_messageSeen, @"CacheInterceptor does not support streaming call"); - if (_messageSeen) { + NSAssert(!_writeMessageSeen, @"CacheInterceptor does not support streaming call"); + if (_writeMessageSeen) { NSLog(@"CacheInterceptor does not support streaming call"); } - _messageSeen = YES; + _writeMessageSeen = YES; _requestMessage = [data copy]; } } - (void)finish { - NSLog(@"finish"); if (!_cacheable) { [_manager finishNextInterceptor]; } else { @@ -236,14 +234,13 @@ _request.path = _requestOptions.path; _request.message = [_requestMessage copy]; _response = [[_context getCachedResponseForRequest:_request] copy]; - NSLog(@"Read cache for %@", _request); if (!_response) { [_manager startNextInterceptorWithRequest:_requestOptions callOptions:_callOptions]; [_manager writeNextInterceptorWithData:_requestMessage]; [_manager finishNextInterceptor]; } else { [_manager forwardPreviousInterceptorWithInitialMetadata:_response.headers]; - [_manager forwardPreviousIntercetporWithData:_response.message]; + [_manager forwardPreviousInterceptorWithData:_response.message]; [_manager forwardPreviousInterceptorCloseWithTrailingMetadata:_response.trailers error:nil]; [_manager shutDown]; } @@ -251,7 +248,6 @@ } - (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { - NSLog(@"initialMetadata"); if (_cacheable) { NSDate *deadline = nil; for (NSString *key in initialMetadata) { @@ -286,15 +282,18 @@ } - (void)didReceiveData:(id)data { - NSLog(@"receiveData"); if (_cacheable) { + NSAssert(!_readMessageSeen, @"CacheInterceptor does not support streaming call"); + if (_readMessageSeen) { + NSLog(@"CacheInterceptor does not support streaming call"); + } + _readMessageSeen = YES; _response.message = [data copy]; } - [_manager forwardPreviousIntercetporWithData:data]; + [_manager forwardPreviousInterceptorWithData:data]; } - (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - NSLog(@"close"); if (error == nil && _cacheable) { _response.trailers = [trailingMetadata copy]; [_context setCachedResponse:_response forRequest:_request]; diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index c96d3436144..6b29d61a173 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -172,19 +172,21 @@ BOOL isRemoteInteropTest(NSString *host) { @interface HookInterceptorFactory : NSObject - (instancetype) - initWithDispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, - GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook -receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, - GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, - GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, - GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; +initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; @@ -194,7 +196,8 @@ receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, - (instancetype) initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - dispatchQueue:(dispatch_queue_t)dispatchQueue + requestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook @@ -222,25 +225,29 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager void (^_responseCloseHook)(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); - dispatch_queue_t _dispatchQueue; + dispatch_queue_t _requestDispatchQueue; + dispatch_queue_t _responseDispatchQueue; } - (instancetype) - initWithDispatchQueue:(dispatch_queue_t)dispatchQueue - startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, - GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook -receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, - GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, - GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, - GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { +initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue + startHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { if ((self = [super init])) { - _dispatchQueue = dispatchQueue; + _requestDispatchQueue = requestDispatchQueue; + _responseDispatchQueue = responseDispatchQueue; _startHook = startHook; _writeDataHook = writeDataHook; _finishHook = finishHook; @@ -249,14 +256,14 @@ receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, _responseDataHook = responseDataHook; _responseCloseHook = responseCloseHook; _didWriteDataHook = didWriteDataHook; - _dispatchQueue = dispatchQueue; } return self; } - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { return [[HookIntercetpor alloc] initWithInterceptorManager:interceptorManager - dispatchQueue:_dispatchQueue + requestDispatchQueue:_requestDispatchQueue + responseDispatchQueue:_responseDispatchQueue startHook:_startHook writeDataHook:_writeDataHook finishHook:_finishHook @@ -281,20 +288,22 @@ receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, GRPCInterceptorManager *manager); void (^_didWriteDataHook)(GRPCInterceptorManager *manager); GRPCInterceptorManager *_manager; - dispatch_queue_t _dispatchQueue; + dispatch_queue_t _requestDispatchQueue; + dispatch_queue_t _responseDispatchQueue; } - (dispatch_queue_t)requestDispatchQueue { - return _dispatchQueue; + return _requestDispatchQueue; } - (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; + return _responseDispatchQueue; } - (instancetype) initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - dispatchQueue:(dispatch_queue_t)dispatchQueue + requestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue startHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook @@ -309,8 +318,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager GRPCInterceptorManager *manager))responseCloseHook didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { if ((self = [super initWithInterceptorManager:interceptorManager - requestDispatchQueue:dispatchQueue - responseDispatchQueue:dispatchQueue])) { + requestDispatchQueue:requestDispatchQueue + responseDispatchQueue:responseDispatchQueue])) { _startHook = startHook; _writeDataHook = writeDataHook; _finishHook = finishHook; @@ -319,7 +328,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager _responseDataHook = responseDataHook; _responseCloseHook = responseCloseHook; _didWriteDataHook = didWriteDataHook; - _dispatchQueue = dispatchQueue; + _requestDispatchQueue = requestDispatchQueue; + _responseDispatchQueue = responseDispatchQueue; _manager = interceptorManager; } return self; @@ -406,7 +416,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } + (void)setUp { - NSLog(@"InteropTest Started, class: %@", [[self class] description]); #ifdef GRPC_COMPILE_WITH_CRONET // Cronet setup [Cronet setHttp2Enabled:YES]; @@ -1316,8 +1325,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } else { [call finish]; } - // DEBUG - NSLog(@"Received message"); } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { @@ -1328,8 +1335,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @"Received %i responses instead of 4.", index); [expectation fulfill]; - // DEBUG - NSLog(@"Received close"); }] callOptions:options]; [call start]; @@ -1351,7 +1356,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block NSUInteger responseCloseCount = 0; __block NSUInteger didWriteDataCount = 0; id factory = [[HookInterceptorFactory alloc] - initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { startCount++; @@ -1371,28 +1377,23 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { receiveNextMessageCount++; - NSLog(@"Interceptor - receive next messages, %lu", (unsigned long)numberOfMessages); [manager receiveNextInterceptorMessages:numberOfMessages]; } responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { responseHeaderCount++; - NSLog(@"Interceptor - received initial metadata, %@", initialMetadata); [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; } responseDataHook:^(id data, GRPCInterceptorManager *manager) { responseDataCount++; - NSLog(@"Interceptor - received data, %@", data); - [manager forwardPreviousIntercetporWithData:data]; + [manager forwardPreviousInterceptorWithData:data]; } responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { responseCloseCount++; - NSLog(@"Interceptor - received close, %@, %@", trailingMetadata, error); [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; } didWriteDataHook:^(GRPCInterceptorManager *manager) { didWriteDataCount++; - NSLog(@"Interceptor - received did-write-data"); [manager forwardPreviousInterceptorDidWriteData]; }]; @@ -1479,7 +1480,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block NSUInteger responseDataCount = 0; __block NSUInteger responseCloseCount = 0; id factory = [[HookInterceptorFactory alloc] - initWithDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { startCount++; @@ -1492,11 +1494,11 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [manager writeNextInterceptorWithData:data]; } else if (index == kCancelAfterWrites) { [manager cancelNextInterceptor]; - [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse + [manager forwardPreviousInterceptorWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; } else { // (index > kCancelAfterWrites) - [manager forwardPreviousIntercetporWithData:[[RMTStreamingOutputCallResponse + [manager forwardPreviousInterceptorWithData:[[RMTStreamingOutputCallResponse messageWithPayloadSize:responses[index]] data]]; } @@ -1514,7 +1516,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } responseDataHook:^(id data, GRPCInterceptorManager *manager) { responseDataCount++; - [manager forwardPreviousIntercetporWithData:data]; + [manager forwardPreviousInterceptorWithData:data]; } responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, GRPCInterceptorManager *manager) { From 757aba8f3c0dc159a3372dc6874fc1069141c0d3 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 28 May 2019 13:58:59 -0700 Subject: [PATCH 159/676] PHP: Fix ZTS build error --- src/php/ext/grpc/php_grpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 1098075690a..74f536ea07b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -203,7 +203,7 @@ void register_fork_handlers() { } } -void apply_ini_settings() { +void apply_ini_settings(TSRMLS_D) { if (GRPC_G(enable_fork_support)) { char *enable_str = malloc(sizeof("GRPC_ENABLE_FORK_SUPPORT=1")); strcpy(enable_str, "GRPC_ENABLE_FORK_SUPPORT=1"); @@ -392,7 +392,7 @@ PHP_MINFO_FUNCTION(grpc) { */ PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { - apply_ini_settings(); + apply_ini_settings(TSRMLS_C); grpc_init(); register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); From 47dbf1dd263e0bf7aba7dbd9651b2bcb570d6889 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 28 May 2019 23:47:29 -0700 Subject: [PATCH 160/676] Second approach --- .../credentials/plugin/plugin_credentials.cc | 62 ++++++++++++------- .../credentials/plugin/plugin_credentials.h | 7 ++- .../lib/security/transport/auth_filters.h | 3 + .../security/transport/client_auth_filter.cc | 16 +++++ src/cpp/client/secure_credentials.cc | 8 ++- test/cpp/end2end/end2end_test.cc | 12 ++-- 6 files changed, 78 insertions(+), 30 deletions(-) diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 8e926de59da..333366d0f0a 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -54,10 +54,15 @@ void grpc_plugin_credentials::pending_request_remove_locked( } } +// Checks if the request has been cancelled. +// If not, removes it from the pending list, so that it cannot be +// cancelled out from under us. +// When this returns, r->cancelled indicates whether the request was +// cancelled before completion. void grpc_plugin_credentials::pending_request_complete(pending_request* r) { GPR_DEBUG_ASSERT(r->creds == this); gpr_mu_lock(&mu_); - pending_request_remove_locked(r); + if (!r->cancelled) pending_request_remove_locked(r); gpr_mu_unlock(&mu_); // Ref to credentials not needed anymore. Unref(); @@ -71,8 +76,7 @@ static grpc_error* process_plugin_result( char* msg; gpr_asprintf(&msg, "Getting metadata from plugin failed with error: %s", error_details); - error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg), - GRPC_ERROR_INT_GRPC_STATUS, status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); } else { bool seen_illegal_header = false; @@ -91,9 +95,7 @@ static grpc_error* process_plugin_result( } } if (seen_illegal_header) { - error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata."), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL); + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Illegal metadata"); } else { for (size_t i = 0; i < num_md; ++i) { grpc_mdelem mdelem = @@ -123,18 +125,19 @@ static void plugin_md_request_metadata_ready(void* request, "asynchronously", r->creds, r); } - // Remove request from pending list + // Remove request from pending list if not previously cancelled. r->creds->pending_request_complete(r); // If it has not been cancelled, process it. - if (r->error == GRPC_ERROR_NONE) { - r->error = process_plugin_result(r, md, num_md, status, error_details); + if (!r->cancelled) { + grpc_error* error = + process_plugin_result(r, md, num_md, status, error_details); + GRPC_CLOSURE_SCHED(r->on_request_metadata, error); } else if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: plugin was previously " "cancelled", r->creds, r); } - GRPC_CLOSURE_SCHED(r->on_request_metadata, r->error); gpr_free(r); } @@ -142,11 +145,11 @@ bool grpc_plugin_credentials::get_request_metadata( grpc_polling_entity* pollent, grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata, grpc_error** error) { + bool retval = true; // Synchronous return. if (plugin_.get_metadata != nullptr) { // Create pending_request object. pending_request* request = static_cast(gpr_zalloc(sizeof(*request))); - request->error = GRPC_ERROR_NONE; request->creds = this; request->md_array = md_array; request->on_request_metadata = on_request_metadata; @@ -180,16 +183,29 @@ bool grpc_plugin_credentials::get_request_metadata( return false; // Asynchronous return. } // Returned synchronously. - // Remove request from pending list. + // Remove request from pending list if not previously cancelled. request->creds->pending_request_complete(request); - if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { - gpr_log(GPR_INFO, - "plugin_credentials[%p]: request %p: plugin returned " - "synchronously", - this, request); + // If the request was cancelled, the error will have been returned + // asynchronously by plugin_cancel_get_request_metadata(), so return + // false. Otherwise, process the result. + if (request->cancelled) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { + gpr_log(GPR_INFO, + "plugin_credentials[%p]: request %p was cancelled, error " + "will be returned asynchronously", + this, request); + } + retval = false; + } else { + if (GRPC_TRACE_FLAG_ENABLED(grpc_plugin_credentials_trace)) { + gpr_log(GPR_INFO, + "plugin_credentials[%p]: request %p: plugin returned " + "synchronously", + this, request); + } + *error = process_plugin_result(request, creds_md, num_creds_md, status, + error_details); } - *error = process_plugin_result(request, creds_md, num_creds_md, status, - error_details); // Clean up. for (size_t i = 0; i < num_creds_md; ++i) { grpc_slice_unref_internal(creds_md[i].key); @@ -198,7 +214,7 @@ bool grpc_plugin_credentials::get_request_metadata( gpr_free((void*)error_details); gpr_free(request); } - return true; // Synchronous return. + return retval; } void grpc_plugin_credentials::cancel_get_request_metadata( @@ -211,11 +227,15 @@ void grpc_plugin_credentials::cancel_get_request_metadata( gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this, pending_request); } - pending_request->error = error; + pending_request->cancelled = true; + GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, + GRPC_ERROR_REF(error)); + pending_request_remove_locked(pending_request); break; } } gpr_mu_unlock(&mu_); + GRPC_ERROR_UNREF(error); } grpc_plugin_credentials::grpc_plugin_credentials( diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h index 7350b37f8a5..77a957e5137 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.h +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h @@ -31,7 +31,7 @@ extern grpc_core::TraceFlag grpc_plugin_credentials_trace; struct grpc_plugin_credentials final : public grpc_call_credentials { public: struct pending_request { - grpc_error* error; + bool cancelled; struct grpc_plugin_credentials* creds; grpc_credentials_mdelem_array* md_array; grpc_closure* on_request_metadata; @@ -51,6 +51,11 @@ struct grpc_plugin_credentials final : public grpc_call_credentials { void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array, grpc_error* error) override; + // Checks if the request has been cancelled. + // If not, removes it from the pending list, so that it cannot be + // cancelled out from under us. + // When this returns, r->cancelled indicates whether the request was + // cancelled before completion. void pending_request_complete(pending_request* r); private: diff --git a/src/core/lib/security/transport/auth_filters.h b/src/core/lib/security/transport/auth_filters.h index 16a8e58ed9a..5e73c21cc44 100644 --- a/src/core/lib/security/transport/auth_filters.h +++ b/src/core/lib/security/transport/auth_filters.h @@ -32,6 +32,9 @@ void grpc_auth_metadata_context_build( const grpc_slice& call_method, grpc_auth_context* auth_context, grpc_auth_metadata_context* auth_md_context); +void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from, + grpc_auth_metadata_context* to); + void grpc_auth_metadata_context_reset(grpc_auth_metadata_context* context); #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H */ diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 40393de2b13..dbe288237d4 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -112,6 +112,20 @@ struct call_data { } // namespace +void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from, + grpc_auth_metadata_context* to) { + grpc_auth_metadata_context_reset(to); + to->channel_auth_context = from->channel_auth_context; + if (to->channel_auth_context != nullptr) { + const_cast(to->channel_auth_context) + ->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context_copy") + .release(); + } + to->service_url = + (from->service_url == nullptr) ? nullptr : strdup(from->service_url); + to->method_name = + (from->method_name == nullptr) ? nullptr : strdup(from->method_name); +} void grpc_auth_metadata_context_reset( grpc_auth_metadata_context* auth_md_context) { if (auth_md_context->service_url != nullptr) { @@ -160,6 +174,8 @@ static void on_credentials_metadata(void* arg, grpc_error* input_error) { if (error == GRPC_ERROR_NONE) { grpc_call_next_op(elem, batch); } else { + error = grpc_error_set_int(error, GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNAVAILABLE); grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); } diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 724a43a9709..2d041a28664 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -22,6 +22,7 @@ #include #include #include +#include "src/core/lib/security/transport/auth_filters.h" #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" @@ -247,10 +248,13 @@ int MetadataCredentialsPluginWrapper::GetMetadata( return true; } if (w->plugin_->IsBlocking()) { + grpc_auth_metadata_context context_copy = grpc_auth_metadata_context(); + grpc_auth_metadata_context_copy(&context, &context_copy); // Asynchronous return. - w->thread_pool_->Add([w, context, cb, user_data] { + w->thread_pool_->Add([w, context_copy, cb, user_data]() mutable { w->MetadataCredentialsPluginWrapper::InvokePlugin( - context, cb, user_data, nullptr, nullptr, nullptr, nullptr); + context_copy, cb, user_data, nullptr, nullptr, nullptr, nullptr); + grpc_auth_metadata_context_reset(&context_copy); }); return 0; } else { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index a505d1a633f..1d699e97b5d 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1849,7 +1849,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::INTERNAL); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); } TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { @@ -1867,7 +1867,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::INTERNAL); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); } TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { @@ -1888,7 +1888,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { Status s = stub_->Echo(&context, request, &response); if (!s.ok()) { - EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code()); + EXPECT_EQ(StatusCode::UNAVAILABLE, s.error_code()); } } @@ -1912,7 +1912,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithCancel) { }); Status s = stub_->Echo(&context, request, &response); if (!s.ok()) { - EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(StatusCode::UNAVAILABLE, s.error_code()); } cancel_thread.join(); } @@ -1933,7 +1933,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::NOT_FOUND); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); @@ -1997,7 +1997,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { Status s = stub_->Echo(&context, request, &response); EXPECT_FALSE(s.ok()); - EXPECT_EQ(s.error_code(), StatusCode::NOT_FOUND); + EXPECT_EQ(s.error_code(), StatusCode::UNAVAILABLE); EXPECT_EQ(s.error_message(), grpc::string("Getting metadata from plugin failed with error: ") + kTestCredsPluginErrorMsg); From 659f71099c163a4046c595460c119fa4cd16829d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 29 May 2019 04:03:47 -0400 Subject: [PATCH 161/676] upgrade bazel toolchain to fix ubsan RBE build --- bazel/grpc_deps.bzl | 8 ++++---- tools/remote_build/rbe_common.bazelrc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index a4e6509782d..db24c7645b0 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -186,11 +186,11 @@ def grpc_deps(): if "bazel_toolchains" not in native.existing_rules(): http_archive( name = "bazel_toolchains", - sha256 = "67335b3563d9b67dc2550b8f27cc689b64fadac491e69ce78763d9ba894cc5cc", - strip_prefix = "bazel-toolchains-cddc376d428ada2927ad359211c3e356bd9c9fbb", + sha256 = "88e818f9f03628eef609c8429c210ecf265ffe46c2af095f36c7ef8b1855fef5", + strip_prefix = "bazel-toolchains-92dd8a7a518a2fb7ba992d47c8b38299fe0be825", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/cddc376d428ada2927ad359211c3e356bd9c9fbb.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz", ], ) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 69394fe092b..63b49c5c42d 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -84,4 +84,4 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top -build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.21.0/ubsan:toolchain +build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.23.0/ubsan:toolchain From 3d52eca5b9a7cddcd1d2b67547c22c28847aa085 Mon Sep 17 00:00:00 2001 From: "1524995078@qq.com" <51152648+OceanOfWest@users.noreply.github.com> Date: Wed, 29 May 2019 16:22:21 +0800 Subject: [PATCH 162/676] fix print format for python3 add brackets of print in run_tests/start_port_server.py --- tools/run_tests/start_port_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py index 0eeceb4ce95..5b776f3b305 100755 --- a/tools/run_tests/start_port_server.py +++ b/tools/run_tests/start_port_server.py @@ -27,4 +27,4 @@ import python_utils.start_port_server as start_port_server start_port_server.start_port_server() -print "Port server started successfully" +print("Port server started successfully") From fa6c944f4c53acd28aa1392f1d3e8045c1340029 Mon Sep 17 00:00:00 2001 From: HarrisonXi Date: Wed, 29 May 2019 18:39:30 +0800 Subject: [PATCH 163/676] remove notification observer to avoid iOS 8 crash --- src/objective-c/GRPCClient/GRPCCall.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 495f94289e7..ba91640269e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -648,6 +648,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)dealloc { + [GRPCConnectivityMonitor unregisterObserver:self]; + __block GRPCWrappedCall *wrappedCall = _wrappedCall; dispatch_async(_callQueue, ^{ wrappedCall = nil; From 9d3288e4082f9be89d75a4d221161443a5feccb8 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 29 May 2019 09:22:17 -0700 Subject: [PATCH 164/676] Fix test bugs --- test/cpp/end2end/end2end_test.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 1d699e97b5d..983714c044a 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1888,7 +1889,8 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { Status s = stub_->Echo(&context, request, &response); if (!s.ok()) { - EXPECT_EQ(StatusCode::UNAVAILABLE, s.error_code()); + EXPECT_TRUE(s.error_code() == StatusCode::DEADLINE_EXCEEDED || + s.error_code() == StatusCode::UNAVAILABLE); } } @@ -1905,14 +1907,15 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithCancel) { true, delay)))); request.set_message("Hello"); - std::thread cancel_thread([&context] { + std::thread cancel_thread([&] { gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(delay, GPR_TIMESPAN))); context.TryCancel(); }); Status s = stub_->Echo(&context, request, &response); if (!s.ok()) { - EXPECT_EQ(StatusCode::UNAVAILABLE, s.error_code()); + EXPECT_TRUE(s.error_code() == StatusCode::CANCELLED || + s.error_code() == StatusCode::UNAVAILABLE); } cancel_thread.join(); } From 8cecf605dac9d1401c5a6611fb92521c9e1c6793 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 26 Mar 2019 14:21:11 -0700 Subject: [PATCH 165/676] add LiteClientBase --- src/csharp/Grpc.Core.Api/LiteClientBase.cs | 96 ++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/csharp/Grpc.Core.Api/LiteClientBase.cs diff --git a/src/csharp/Grpc.Core.Api/LiteClientBase.cs b/src/csharp/Grpc.Core.Api/LiteClientBase.cs new file mode 100644 index 00000000000..a978cdf09e0 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/LiteClientBase.cs @@ -0,0 +1,96 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; + +namespace Grpc.Core +{ + /// + /// Base class for lightweight client-side stubs. + /// All calls are invoked via a CallInvoker. + /// Lite client stubs have no configuration knobs, all configuration + /// is provided by decorating the call invoker. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public abstract class LiteClientBase + { + readonly CallInvoker callInvoker; + + /// + /// Initializes a new instance of LiteClientBase class that + /// throws NotImplementedException upon invocation of any RPC. + /// This constructor is only provided to allow creation of test doubles + /// for client classes (e.g. mocking requires a parameterless constructor). + /// + protected LiteClientBase() : this(new UnimplementedCallInvoker()) + { + } + + /// + /// Initializes a new instance of ClientBase class. + /// + /// The CallInvoker for remote call invocation. + public LiteClientBase(CallInvoker callInvoker) + { + this.callInvoker = callInvoker; + } + + /// + /// Gets the call invoker. + /// + protected CallInvoker CallInvoker + { + get { return this.callInvoker; } + } + + /// + /// Call invoker that throws NotImplementedException for all requests. + /// + private class UnimplementedCallInvoker : CallInvoker + { + public UnimplementedCallInvoker() + { + } + + public override TResponse BlockingUnaryCall(Method method, string host, CallOptions options, TRequest request) + { + throw new NotImplementedException(); + } + + public override AsyncUnaryCall AsyncUnaryCall(Method method, string host, CallOptions options, TRequest request) + { + throw new NotImplementedException(); + } + + public override AsyncServerStreamingCall AsyncServerStreamingCall(Method method, string host, CallOptions options, TRequest request) + { + throw new NotImplementedException(); + } + + public override AsyncClientStreamingCall AsyncClientStreamingCall(Method method, string host, CallOptions options) + { + throw new NotImplementedException(); + } + + public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall(Method method, string host, CallOptions options) + { + throw new NotImplementedException(); + } + } + } +} From 25e3d26e8cb361692101555cdb199933079cd90f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 26 Apr 2019 07:37:21 -0400 Subject: [PATCH 166/676] C# lite client codegen --- src/compiler/csharp_generator.cc | 116 ++++++++++++++++++------------- src/compiler/csharp_generator.h | 4 +- src/compiler/csharp_plugin.cc | 7 +- 3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 778e5c39284..10737c5e8db 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -176,8 +176,9 @@ std::string GetServiceClassName(const ServiceDescriptor* service) { return service->name(); } -std::string GetClientClassName(const ServiceDescriptor* service) { - return service->name() + "Client"; +std::string GetClientClassName(const ServiceDescriptor* service, + bool lite_client) { + return service->name() + (lite_client ? "LiteClient" : "Client"); } std::string GetServerClassName(const ServiceDescriptor* service) { @@ -414,24 +415,34 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) { out->Print("\n"); } -void GenerateClientStub(Printer* out, const ServiceDescriptor* service) { - out->Print("/// Client for $servicename$\n", "servicename", - GetServiceClassName(service)); - out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", "name", - GetClientClassName(service)); +void GenerateClientStub(Printer* out, const ServiceDescriptor* service, + bool lite_client) { + if (!lite_client) { + out->Print("/// Client for $servicename$\n", + "servicename", GetServiceClassName(service)); + out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", + "name", GetClientClassName(service, lite_client)); + } else { + out->Print("/// Lite client for $servicename$\n", + "servicename", GetServiceClassName(service)); + out->Print("public partial class $name$ : grpc::LiteClientBase\n", "name", + GetClientClassName(service, lite_client)); + } out->Print("{\n"); out->Indent(); // constructors - out->Print( - "/// Creates a new client for $servicename$\n" - "/// The channel to use to make remote " - "calls.\n", - "servicename", GetServiceClassName(service)); - out->Print("public $name$(grpc::Channel channel) : base(channel)\n", "name", - GetClientClassName(service)); - out->Print("{\n"); - out->Print("}\n"); + if (!lite_client) { + out->Print( + "/// Creates a new client for $servicename$\n" + "/// The channel to use to make remote " + "calls.\n", + "servicename", GetServiceClassName(service)); + out->Print("public $name$(grpc::Channel channel) : base(channel)\n", "name", + GetClientClassName(service, lite_client)); + out->Print("{\n"); + out->Print("}\n"); + } out->Print( "/// Creates a new client for $servicename$ that uses a custom " "CallInvoker.\n" @@ -440,26 +451,30 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service) { "servicename", GetServiceClassName(service)); out->Print( "public $name$(grpc::CallInvoker callInvoker) : base(callInvoker)\n", - "name", GetClientClassName(service)); + "name", GetClientClassName(service, lite_client)); out->Print("{\n"); out->Print("}\n"); out->Print( "/// Protected parameterless constructor to allow creation" " of test doubles.\n"); out->Print("protected $name$() : base()\n", "name", - GetClientClassName(service)); + GetClientClassName(service, lite_client)); out->Print("{\n"); out->Print("}\n"); - out->Print( - "/// Protected constructor to allow creation of configured " - "clients.\n" - "/// The client configuration.\n"); - out->Print( - "protected $name$(ClientBaseConfiguration configuration)" - " : base(configuration)\n", - "name", GetClientClassName(service)); - out->Print("{\n"); - out->Print("}\n\n"); + if (!lite_client) { + out->Print( + "/// Protected constructor to allow creation of configured " + "clients.\n" + "/// The client " + "configuration.\n"); + out->Print( + "protected $name$(ClientBaseConfiguration configuration)" + " : base(configuration)\n", + "name", GetClientClassName(service, lite_client)); + out->Print("{\n"); + out->Print("}\n"); + } + out->Print("\n"); for (int i = 0; i < service->method_count(); i++) { const MethodDescriptor* method = service->method(i); @@ -577,19 +592,21 @@ 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", - "name", GetClientClassName(service)); - out->Print("{\n"); - out->Indent(); - out->Print("return new $name$(configuration);\n", "name", - GetClientClassName(service)); - out->Outdent(); - out->Print("}\n"); + if (!lite_client) { + out->Print( + "/// Creates a new instance of client from given " + "ClientBaseConfiguration.\n"); + out->Print( + "protected override $name$ NewInstance(ClientBaseConfiguration " + "configuration)\n", + "name", GetClientClassName(service, lite_client)); + out->Print("{\n"); + out->Indent(); + out->Print("return new $name$(configuration);\n", "name", + GetClientClassName(service, lite_client)); + out->Outdent(); + out->Print("}\n"); + } out->Outdent(); out->Print("}\n"); @@ -670,8 +687,8 @@ void GenerateBindServiceWithBinderMethod(Printer* out, } void GenerateService(Printer* out, const ServiceDescriptor* service, - bool generate_client, bool generate_server, - bool internal_access) { + bool generate_client, bool generate_lite_client, + bool generate_server, bool internal_access) { GenerateDocCommentBody(out, service); out->Print("$access_level$ static partial class $classname$\n", "access_level", GetAccessLevel(internal_access), "classname", @@ -693,8 +710,12 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, GenerateServerClass(out, service); } if (generate_client) { - GenerateClientStub(out, service); + GenerateClientStub(out, service, false); } + if (generate_lite_client) { + GenerateClientStub(out, service, true); + } + if (generate_server) { GenerateBindServiceMethod(out, service); GenerateBindServiceWithBinderMethod(out, service); @@ -707,7 +728,8 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, } // anonymous namespace grpc::string GetServices(const FileDescriptor* file, bool generate_client, - bool generate_server, bool internal_access) { + bool generate_lite_client, bool generate_server, + bool internal_access) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -748,8 +770,8 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client, out.Indent(); } for (int i = 0; i < file->service_count(); i++) { - GenerateService(&out, file->service(i), generate_client, generate_server, - internal_access); + GenerateService(&out, file->service(i), generate_client, + generate_lite_client, generate_server, internal_access); } if (file_namespace != "") { out.Outdent(); diff --git a/src/compiler/csharp_generator.h b/src/compiler/csharp_generator.h index fd36e11851b..842d136494c 100644 --- a/src/compiler/csharp_generator.h +++ b/src/compiler/csharp_generator.h @@ -26,8 +26,8 @@ namespace grpc_csharp_generator { grpc::string GetServices(const grpc::protobuf::FileDescriptor* file, - bool generate_client, bool generate_server, - bool internal_access); + bool generate_client, bool generate_lite_client, + bool generate_server, bool internal_access); } // namespace grpc_csharp_generator diff --git a/src/compiler/csharp_plugin.cc b/src/compiler/csharp_plugin.cc index 5f13aa6749e..a495f876792 100644 --- a/src/compiler/csharp_plugin.cc +++ b/src/compiler/csharp_plugin.cc @@ -38,10 +38,14 @@ class CSharpGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { bool generate_client = true; bool generate_server = true; + bool generate_lite_client = true; bool internal_access = false; for (size_t i = 0; i < options.size(); i++) { if (options[i].first == "no_client") { generate_client = false; + } else if (options[i].first == "no_lite_client") { + // TODO: better option + generate_lite_client = false; } else if (options[i].first == "no_server") { generate_server = false; } else if (options[i].first == "internal_access") { @@ -53,7 +57,8 @@ class CSharpGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { } grpc::string code = grpc_csharp_generator::GetServices( - file, generate_client, generate_server, internal_access); + file, generate_client, generate_lite_client, generate_server, + internal_access); if (code.size() == 0) { return true; // don't generate a file if there are no services } From 285cea16b3151ce7296e3d370d5e3683e80f8cb3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 29 May 2019 10:14:52 -0700 Subject: [PATCH 167/676] Reorganize tests --- src/objective-c/tests/run_one_test.sh | 49 +++++++++++ tools/run_tests/run_tests.py | 116 +++++++++++++++----------- tools/run_tests/run_tests_matrix.py | 4 +- 3 files changed, 119 insertions(+), 50 deletions(-) create mode 100644 src/objective-c/tests/run_one_test.sh diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh new file mode 100644 index 00000000000..af8a5b6351e --- /dev/null +++ b/src/objective-c/tests/run_one_test.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Don't run this script standalone. Instead, run from the repository root: +# ./tools/run_tests/run_tests.py -l objc + +set -ev + +cd $(dirname $0) + +BINDIR=../../../bins/$CONFIG + +[ -f $BINDIR/interop_server ] || { + echo >&2 "Can't find the test server. Make sure run_tests.py is making" \ + "interop_server before calling this script." + exit 1 +} +$BINDIR/interop_server --port=5050 --max_send_message_size=8388608 & +$BINDIR/interop_server --port=5051 --max_send_message_size=8388608 --use_tls & + +trap 'kill -9 `jobs -p` ; echo "EXIT TIME: $(date)"' EXIT + +set -o pipefail + +XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )' + +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme SCHEME \ + -destination name="iPhone 8" \ + HOST_PORT_LOCALSSL=localhost:5051 \ + HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a7a9dbd48d0..d99bbf43ffa 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1048,54 +1048,74 @@ class ObjCLanguage(object): _check_compiler(self.args.compiler, ['default']) def test_specs(self): - return [ - self.config.job_spec( - ['src/objective-c/tests/run_tests.sh'], - timeout_seconds=60 * 60, - shortname='objc-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec( - ['src/objective-c/tests/run_plugin_tests.sh'], - timeout_seconds=60 * 60, - shortname='objc-plugin-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-sample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-sample-frameworks', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', - 'FRAMEWORKS': 'YES' - }), - self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='objc-build-example-switftsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'SwiftSample', - 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' - }), - self.config.job_spec( - ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=20 * 60, - shortname='cfstream-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS), - ] + out = [] + if self.config == 'dbg': + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' + }) + out += job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample-frameworks', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', + 'FRAMEWORKS': 'YES' + }) + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-switftsample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'SwiftSample', + 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_plugin_tests.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-plugintest', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], + timeout_seconds=20 * 60, + shortname='ios-test-cfstream-tests', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-unittests', + cpu_cost=1e6, + environ={SCHEME: 'UnitTests'}) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-interoptests', + cpu_cost=1e6, + environ={SCHEME: 'InteropTests'}) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-cronettests', + cpu_cost=1e6, + environ={SCHEME: 'CronetTests'}) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='mac-test-basictests', + cpu_cost=1e6, + environ={SCHEME: 'MacTests'}) + + return sorted(out); def pre_build_steps(self): return [] diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 785dff36eab..cfd67b99f34 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -246,10 +246,10 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): # supported on mac only. test_jobs += _generate_jobs( languages=['objc'], - configs=['dbg', 'opt'], + configs=['dbg'], platforms=['macos'], labels=['basictests', 'multilang'], - extra_args=extra_args, + extra_args=extra_args + os.getenv('GRPC_OBJC_TEST_EXTRA_ARGS', '.*'), inner_jobs=inner_jobs, timeout_seconds=_OBJC_RUNTESTS_TIMEOUT) From d835d1bb1f455fd150b10aa2125659b404697db2 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 29 May 2019 10:41:38 -0700 Subject: [PATCH 168/676] Surface exception from metadata credentails plugin methods --- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi | 4 ++-- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 4 ++-- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index af069acc287..05892b37324 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -26,9 +26,9 @@ cdef int _get_metadata( grpc_credentials_plugin_metadata_cb cb, void *user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, - const char **error_details) with gil + const char **error_details) except * with gil -cdef void _destroy(void *state) with gil +cdef void _destroy(void *state) except * with gil cdef class MetadataPluginCallCredentials(CallCredentials): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 52ca92f2e9f..2ec1c0bc427 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -42,7 +42,7 @@ cdef int _get_metadata( grpc_credentials_plugin_metadata_cb cb, void *user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, - const char **error_details) with gil: + const char **error_details) except * with gil: cdef size_t metadata_count cdef grpc_metadata *c_metadata def callback(metadata, grpc_status_code status, bytes error_details): @@ -57,7 +57,7 @@ cdef int _get_metadata( return 0 # Asynchronous return -cdef void _destroy(void *state) with gil: +cdef void _destroy(void *state) except * with gil: cpython.Py_DECREF(state) grpc_shutdown_blocking() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 057d0776983..a674c34bb23 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -546,8 +546,8 @@ cdef extern from "grpc/grpc_security.h": grpc_credentials_plugin_metadata_cb cb, void *user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t *num_creds_md, grpc_status_code *status, - const char **error_details) - void (*destroy)(void *state) + const char **error_details) except * + void (*destroy)(void *state) except * void *state const char *type From 1b8418b5460a63c331288cd475db7198cb2c494a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 29 May 2019 13:37:48 -0400 Subject: [PATCH 169/676] only generate full or lite client, never both --- src/compiler/csharp_generator.cc | 38 ++++++++++++++------------------ src/compiler/csharp_generator.h | 4 ++-- src/compiler/csharp_plugin.cc | 12 +++++----- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 10737c5e8db..a45408a4cb8 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -176,9 +176,8 @@ std::string GetServiceClassName(const ServiceDescriptor* service) { return service->name(); } -std::string GetClientClassName(const ServiceDescriptor* service, - bool lite_client) { - return service->name() + (lite_client ? "LiteClient" : "Client"); +std::string GetClientClassName(const ServiceDescriptor* service) { + return service->name() + "Client"; } std::string GetServerClassName(const ServiceDescriptor* service) { @@ -421,12 +420,12 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service, out->Print("/// Client for $servicename$\n", "servicename", GetServiceClassName(service)); out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", - "name", GetClientClassName(service, lite_client)); + "name", GetClientClassName(service)); } else { out->Print("/// Lite client for $servicename$\n", "servicename", GetServiceClassName(service)); out->Print("public partial class $name$ : grpc::LiteClientBase\n", "name", - GetClientClassName(service, lite_client)); + GetClientClassName(service)); } out->Print("{\n"); out->Indent(); @@ -439,7 +438,7 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service, "calls.\n", "servicename", GetServiceClassName(service)); out->Print("public $name$(grpc::Channel channel) : base(channel)\n", "name", - GetClientClassName(service, lite_client)); + GetClientClassName(service)); out->Print("{\n"); out->Print("}\n"); } @@ -451,14 +450,14 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service, "servicename", GetServiceClassName(service)); out->Print( "public $name$(grpc::CallInvoker callInvoker) : base(callInvoker)\n", - "name", GetClientClassName(service, lite_client)); + "name", GetClientClassName(service)); out->Print("{\n"); out->Print("}\n"); out->Print( "/// Protected parameterless constructor to allow creation" " of test doubles.\n"); out->Print("protected $name$() : base()\n", "name", - GetClientClassName(service, lite_client)); + GetClientClassName(service)); out->Print("{\n"); out->Print("}\n"); if (!lite_client) { @@ -470,7 +469,7 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service, out->Print( "protected $name$(ClientBaseConfiguration configuration)" " : base(configuration)\n", - "name", GetClientClassName(service, lite_client)); + "name", GetClientClassName(service)); out->Print("{\n"); out->Print("}\n"); } @@ -599,11 +598,11 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service, out->Print( "protected override $name$ NewInstance(ClientBaseConfiguration " "configuration)\n", - "name", GetClientClassName(service, lite_client)); + "name", GetClientClassName(service)); out->Print("{\n"); out->Indent(); out->Print("return new $name$(configuration);\n", "name", - GetClientClassName(service, lite_client)); + GetClientClassName(service)); out->Outdent(); out->Print("}\n"); } @@ -687,8 +686,8 @@ void GenerateBindServiceWithBinderMethod(Printer* out, } void GenerateService(Printer* out, const ServiceDescriptor* service, - bool generate_client, bool generate_lite_client, - bool generate_server, bool internal_access) { + bool generate_client, bool generate_server, + bool internal_access, bool lite_client) { GenerateDocCommentBody(out, service); out->Print("$access_level$ static partial class $classname$\n", "access_level", GetAccessLevel(internal_access), "classname", @@ -710,10 +709,7 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, GenerateServerClass(out, service); } if (generate_client) { - GenerateClientStub(out, service, false); - } - if (generate_lite_client) { - GenerateClientStub(out, service, true); + GenerateClientStub(out, service, lite_client); } if (generate_server) { @@ -728,8 +724,8 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, } // anonymous namespace grpc::string GetServices(const FileDescriptor* file, bool generate_client, - bool generate_lite_client, bool generate_server, - bool internal_access) { + bool generate_server, bool internal_access, + bool lite_client) { grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. @@ -770,8 +766,8 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client, out.Indent(); } for (int i = 0; i < file->service_count(); i++) { - GenerateService(&out, file->service(i), generate_client, - generate_lite_client, generate_server, internal_access); + GenerateService(&out, file->service(i), generate_client, generate_server, + internal_access, lite_client); } if (file_namespace != "") { out.Outdent(); diff --git a/src/compiler/csharp_generator.h b/src/compiler/csharp_generator.h index 842d136494c..d4c13c67363 100644 --- a/src/compiler/csharp_generator.h +++ b/src/compiler/csharp_generator.h @@ -26,8 +26,8 @@ namespace grpc_csharp_generator { grpc::string GetServices(const grpc::protobuf::FileDescriptor* file, - bool generate_client, bool generate_lite_client, - bool generate_server, bool internal_access); + bool generate_client, bool generate_server, + bool internal_access, bool lite_client); } // namespace grpc_csharp_generator diff --git a/src/compiler/csharp_plugin.cc b/src/compiler/csharp_plugin.cc index a495f876792..c503fd61ded 100644 --- a/src/compiler/csharp_plugin.cc +++ b/src/compiler/csharp_plugin.cc @@ -38,18 +38,19 @@ class CSharpGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { bool generate_client = true; bool generate_server = true; - bool generate_lite_client = true; bool internal_access = false; + bool lite_client = false; for (size_t i = 0; i < options.size(); i++) { if (options[i].first == "no_client") { generate_client = false; - } else if (options[i].first == "no_lite_client") { - // TODO: better option - generate_lite_client = false; } else if (options[i].first == "no_server") { generate_server = false; } else if (options[i].first == "internal_access") { internal_access = true; + } else if (options[i].first == "lite_client") { + // will only be used if generate_client is true. + // NOTE: experimental option, can be removed in future release + lite_client = true; } else { *error = "Unknown generator option: " + options[i].first; return false; @@ -57,8 +58,7 @@ class CSharpGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { } grpc::string code = grpc_csharp_generator::GetServices( - file, generate_client, generate_lite_client, generate_server, - internal_access); + file, generate_client, generate_server, internal_access, lite_client); if (code.size() == 0) { return true; // don't generate a file if there are no services } From 81a2c849abf822870667a54476f26c29ee867529 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 26 Apr 2019 07:38:40 -0400 Subject: [PATCH 170/676] regenerate C# protos --- .../Grpc.IntegrationTesting/EchoMessages.cs | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs index e5af4a93e99..bbba68eeac1 100644 --- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs +++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs @@ -28,7 +28,7 @@ namespace Grpc.Testing { "DGdycGMudGVzdGluZyIyCglEZWJ1Z0luZm8SFQoNc3RhY2tfZW50cmllcxgB", "IAMoCRIOCgZkZXRhaWwYAiABKAkiUAoLRXJyb3JTdGF0dXMSDAoEY29kZRgB", "IAEoBRIVCg1lcnJvcl9tZXNzYWdlGAIgASgJEhwKFGJpbmFyeV9lcnJvcl9k", - "ZXRhaWxzGAMgASgJIv8DCg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", + "ZXRhaWxzGAMgASgJIqAECg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", "bmUYASABKAgSHgoWY2xpZW50X2NhbmNlbF9hZnRlcl91cxgCIAEoBRIeChZz", "ZXJ2ZXJfY2FuY2VsX2FmdGVyX3VzGAMgASgFEhUKDWVjaG9fbWV0YWRhdGEY", "BCABKAgSGgoSY2hlY2tfYXV0aF9jb250ZXh0GAUgASgIEh8KF3Jlc3BvbnNl", @@ -39,18 +39,19 @@ namespace Grpc.Testing { "Zy5EZWJ1Z0luZm8SEgoKc2VydmVyX2RpZRgMIAEoCBIcChRiaW5hcnlfZXJy", "b3JfZGV0YWlscxgNIAEoCRIxCg5leHBlY3RlZF9lcnJvchgOIAEoCzIZLmdy", "cGMudGVzdGluZy5FcnJvclN0YXR1cxIXCg9zZXJ2ZXJfc2xlZXBfdXMYDyAB", - "KAUSGwoTYmFja2VuZF9jaGFubmVsX2lkeBgQIAEoBSJKCgtFY2hvUmVxdWVz", - "dBIPCgdtZXNzYWdlGAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0", - "aW5nLlJlcXVlc3RQYXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVz", - "dF9kZWFkbGluZRgBIAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAki", - "TAoMRWNob1Jlc3BvbnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiAB", - "KAsyHC5ncnBjLnRlc3RpbmcuUmVzcG9uc2VQYXJhbXNiBnByb3RvMw==")); + "KAUSGwoTYmFja2VuZF9jaGFubmVsX2lkeBgQIAEoBRIfChdlY2hvX21ldGFk", + "YXRhX2luaXRpYWxseRgRIAEoCCJKCgtFY2hvUmVxdWVzdBIPCgdtZXNzYWdl", + "GAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0aW5nLlJlcXVlc3RQ", + "YXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVzdF9kZWFkbGluZRgB", + "IAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAkiTAoMRWNob1Jlc3Bv", + "bnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiABKAsyHC5ncnBjLnRl", + "c3RpbmcuUmVzcG9uc2VQYXJhbXNCA/gBAWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.DebugInfo), global::Grpc.Testing.DebugInfo.Parser, new[]{ "StackEntries", "Detail" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ErrorStatus), global::Grpc.Testing.ErrorStatus.Parser, new[]{ "Code", "ErrorMessage", "BinaryErrorDetails" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError", "ServerSleepUs", "BackendChannelIdx" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError", "ServerSleepUs", "BackendChannelIdx", "EchoMetadataInitially" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoRequest), global::Grpc.Testing.EchoRequest.Parser, new[]{ "Message", "Param" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ResponseParams), global::Grpc.Testing.ResponseParams.Parser, new[]{ "RequestDeadline", "Host", "Peer" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoResponse), global::Grpc.Testing.EchoResponse.Parser, new[]{ "Message", "Param" }, null, null, null) @@ -441,6 +442,7 @@ namespace Grpc.Testing { expectedError_ = other.expectedError_ != null ? other.expectedError_.Clone() : null; serverSleepUs_ = other.serverSleepUs_; backendChannelIdx_ = other.backendChannelIdx_; + echoMetadataInitially_ = other.echoMetadataInitially_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -637,6 +639,17 @@ namespace Grpc.Testing { } } + /// Field number for the "echo_metadata_initially" field. + public const int EchoMetadataInitiallyFieldNumber = 17; + private bool echoMetadataInitially_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool EchoMetadataInitially { + get { return echoMetadataInitially_; } + set { + echoMetadataInitially_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as RequestParams); @@ -666,6 +679,7 @@ namespace Grpc.Testing { if (!object.Equals(ExpectedError, other.ExpectedError)) return false; if (ServerSleepUs != other.ServerSleepUs) return false; if (BackendChannelIdx != other.BackendChannelIdx) return false; + if (EchoMetadataInitially != other.EchoMetadataInitially) return false; return Equals(_unknownFields, other._unknownFields); } @@ -688,6 +702,7 @@ namespace Grpc.Testing { if (expectedError_ != null) hash ^= ExpectedError.GetHashCode(); if (ServerSleepUs != 0) hash ^= ServerSleepUs.GetHashCode(); if (BackendChannelIdx != 0) hash ^= BackendChannelIdx.GetHashCode(); + if (EchoMetadataInitially != false) hash ^= EchoMetadataInitially.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -765,6 +780,10 @@ namespace Grpc.Testing { output.WriteRawTag(128, 1); output.WriteInt32(BackendChannelIdx); } + if (EchoMetadataInitially != false) { + output.WriteRawTag(136, 1); + output.WriteBool(EchoMetadataInitially); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -821,6 +840,9 @@ namespace Grpc.Testing { if (BackendChannelIdx != 0) { size += 2 + pb::CodedOutputStream.ComputeInt32Size(BackendChannelIdx); } + if (EchoMetadataInitially != false) { + size += 2 + 1; + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -886,6 +908,9 @@ namespace Grpc.Testing { if (other.BackendChannelIdx != 0) { BackendChannelIdx = other.BackendChannelIdx; } + if (other.EchoMetadataInitially != false) { + EchoMetadataInitially = other.EchoMetadataInitially; + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -967,6 +992,10 @@ namespace Grpc.Testing { BackendChannelIdx = input.ReadInt32(); break; } + case 136: { + EchoMetadataInitially = input.ReadBool(); + break; + } } } } From 5ab4022fcf97ba78333689c96870da7c162d9610 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 29 May 2019 10:47:25 -0700 Subject: [PATCH 171/676] update kokoro cfg files --- ..._objc_dbg.cfg => grpc_basictests_objc.cfg} | 5 +++ .../macos/grpc_buildtests_objc.cfg | 36 +++++++++++++++++++ ...ts_objc_opt.cfg => grpc_mactests_objc.cfg} | 7 +++- 3 files changed, 47 insertions(+), 1 deletion(-) rename tools/internal_ci/macos/{grpc_basictests_objc_dbg.cfg => grpc_basictests_objc.cfg} (93%) create mode 100644 tools/internal_ci/macos/grpc_buildtests_objc.cfg rename tools/internal_ci/macos/{grpc_basictests_objc_opt.cfg => grpc_mactests_objc.cfg} (88%) diff --git a/tools/internal_ci/macos/grpc_basictests_objc_dbg.cfg b/tools/internal_ci/macos/grpc_basictests_objc.cfg similarity index 93% rename from tools/internal_ci/macos/grpc_basictests_objc_dbg.cfg rename to tools/internal_ci/macos/grpc_basictests_objc.cfg index 068961234be..6563fa69d02 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc_dbg.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc.cfg @@ -29,3 +29,8 @@ env_vars { key: "RUN_TESTS_FLAGS" value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" } + +env_vars { + key: "GRPC_OBJC_TEST_EXTRA_ARGS" + value: "-r ios-test-.*" +} diff --git a/tools/internal_ci/macos/grpc_buildtests_objc.cfg b/tools/internal_ci/macos/grpc_buildtests_objc.cfg new file mode 100644 index 00000000000..d1a802eef5e --- /dev/null +++ b/tools/internal_ci/macos/grpc_buildtests_objc.cfg @@ -0,0 +1,36 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} + +env_vars { + key: "GRPC_OBJC_TEST_EXTRA_ARGS" + value: "-r ios-buildtest-.*" +} diff --git a/tools/internal_ci/macos/grpc_basictests_objc_opt.cfg b/tools/internal_ci/macos/grpc_mactests_objc.cfg similarity index 88% rename from tools/internal_ci/macos/grpc_basictests_objc_opt.cfg rename to tools/internal_ci/macos/grpc_mactests_objc.cfg index 927fa50deb0..945bcb8c466 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc_opt.cfg +++ b/tools/internal_ci/macos/grpc_mactests_objc.cfg @@ -27,5 +27,10 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} + +env_vars { + key: "GRPC_OBJC_TEST_EXTRA_ARGS" + value: "-r mac-test-.*" } From b790c24e5c3b0135a16e472a7badb868334d7eb6 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 29 May 2019 11:20:36 -0700 Subject: [PATCH 172/676] Revert "Start supporting a callback-based RPC under lock" --- src/core/lib/surface/completion_queue.cc | 85 ++++++++----------- src/core/lib/surface/completion_queue.h | 3 +- src/core/lib/surface/server.cc | 2 +- test/core/surface/completion_queue_test.cc | 44 +--------- .../end2end/client_callback_end2end_test.cc | 28 ------ test/cpp/microbenchmarks/bm_cq.cc | 35 +------- .../callback_streaming_ping_pong.h | 2 +- 7 files changed, 42 insertions(+), 157 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index d0ed1a9f673..e796071eedc 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -34,7 +34,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gprpp/atomic.h" -#include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" @@ -201,7 +200,7 @@ struct cq_vtable { bool (*begin_op)(grpc_completion_queue* cq, void* tag); void (*end_op)(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, bool internal); + void* done_arg, grpc_cq_completion* storage); grpc_event (*next)(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, @@ -355,20 +354,23 @@ static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); // queue. The done argument is a callback that will be invoked when it is // safe to free up that storage. The storage MUST NOT be freed until the // done callback is invoked. -static void cq_end_op_for_next( - grpc_completion_queue* cq, void* tag, grpc_error* error, - void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal); - -static void cq_end_op_for_pluck( - grpc_completion_queue* cq, void* tag, grpc_error* error, - void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal); - -static void cq_end_op_for_callback( - grpc_completion_queue* cq, void* tag, grpc_error* error, - void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal); +static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage); + +static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage); + +static void cq_end_op_for_callback(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -672,10 +674,11 @@ bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_NEXT) */ -static void cq_end_op_for_next( - grpc_completion_queue* cq, void* tag, grpc_error* error, - void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { +static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -751,10 +754,11 @@ static void cq_end_op_for_next( /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_PLUCK) */ -static void cq_end_op_for_pluck( - grpc_completion_queue* cq, void* tag, grpc_error* error, - void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { +static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -817,19 +821,15 @@ static void cq_end_op_for_pluck( GRPC_ERROR_UNREF(error); } -static void functor_callback(void* arg, grpc_error* error) { - auto* functor = static_cast(arg); - functor->functor_run(functor, error == GRPC_ERROR_NONE); -} - /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage, bool internal) { + grpc_cq_completion* storage) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); + bool is_success = (error == GRPC_ERROR_NONE); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && @@ -856,25 +856,16 @@ static void cq_end_op_for_callback( cq_finish_shutdown_callback(cq); } - auto* functor = static_cast(tag); - if (internal) { - grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, - (error == GRPC_ERROR_NONE)); - } else { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); - } GRPC_ERROR_UNREF(error); + + auto* functor = static_cast(tag); + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, is_success); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal) { - cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); + void* done_arg, grpc_cq_completion* storage) { + cq->vtable->end_op(cq, tag, error, done, done_arg, storage); } typedef struct { @@ -1352,11 +1343,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, callback, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); } static void cq_shutdown_callback(grpc_completion_queue* cq) { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 3ba9fbb8765..d60fe6d6efe 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,8 +77,7 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage, - bool internal = false); + void* done_arg, grpc_cq_completion* storage); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 44de0cd42dd..5ecd5662c2c 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx, } grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event, - rc, &rc->completion, true); + rc, &rc->completion); } static void publish_new_rpc(void* arg, grpc_error* error) { diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 4a33b934f43..7c3630eaf18 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -23,7 +23,6 @@ #include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -360,19 +359,12 @@ static void test_pluck_after_shutdown(void) { static void test_callback(void) { grpc_completion_queue* cc; - static void* tags[128]; + void* tags[128]; grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; grpc_cq_polling_type polling_types[] = { GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING}; grpc_completion_queue_attributes attr; unsigned i; - static gpr_mu mu, shutdown_mu; - static gpr_cv cv, shutdown_cv; - static int cb_counter; - gpr_mu_init(&mu); - gpr_mu_init(&shutdown_mu); - gpr_cv_init(&cv); - gpr_cv_init(&shutdown_cv); LOG_TEST("test_callback"); @@ -384,11 +376,7 @@ static void test_callback(void) { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); - // Signal when the shutdown callback is completed. - gpr_cv_signal(&shutdown_cv); - gpr_mu_unlock(&shutdown_mu); } private: @@ -403,9 +391,9 @@ static void test_callback(void) { for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { int sumtags = 0; int counter = 0; - cb_counter = 0; { // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; attr.cq_polling_type = polling_types[pidx]; cc = grpc_completion_queue_create( @@ -421,13 +409,7 @@ static void test_callback(void) { int ok) { GPR_ASSERT(static_cast(ok)); auto* callback = static_cast(cb); - gpr_mu_lock(&mu); - cb_counter++; *callback->counter_ += callback->tag_; - if (cb_counter == GPR_ARRAY_SIZE(tags)) { - gpr_cv_signal(&cv); - } - gpr_mu_unlock(&mu); grpc_core::Delete(callback); }; @@ -447,34 +429,12 @@ static void test_callback(void) { nullptr, &completions[i]); } - gpr_mu_lock(&mu); - while (cb_counter != GPR_ARRAY_SIZE(tags)) { - // Wait for all the callbacks to complete. - gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); - } - gpr_mu_unlock(&mu); - shutdown_and_destroy(cc); - - gpr_mu_lock(&shutdown_mu); - while (!got_shutdown) { - // Wait for the shutdown callback to complete. - gpr_cv_wait(&shutdown_cv, &shutdown_mu, - gpr_inf_future(GPR_CLOCK_REALTIME)); - } - gpr_mu_unlock(&shutdown_mu); } - - // Run the assertions to check if the test ran successfully. GPR_ASSERT(sumtags == counter); GPR_ASSERT(got_shutdown); got_shutdown = false; } - - gpr_cv_destroy(&cv); - gpr_cv_destroy(&shutdown_cv); - gpr_mu_destroy(&mu); - gpr_mu_destroy(&shutdown_mu); } struct thread_state { diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 8cf6def1073..a154324216b 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -374,34 +374,6 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { SendRpcs(1, false); } -TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { - MAYBE_SKIP_TEST; - ResetStub(); - std::mutex mu; - std::condition_variable cv; - bool done = false; - EchoRequest request; - request.set_message("Hello locked world."); - EchoResponse response; - ClientContext cli_ctx; - { - std::lock_guard l(mu); - stub_->experimental_async()->Echo( - &cli_ctx, &request, &response, - [&mu, &cv, &done, &request, &response](Status s) { - std::lock_guard l(mu); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(request.message(), response.message()); - done = true; - cv.notify_one(); - }); - } - std::unique_lock l(mu); - while (!done) { - cv.wait(l); - } -} - TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { MAYBE_SKIP_TEST; ResetStub(); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index edbff9c2be3..50eb9454fbe 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -150,9 +150,6 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { grpc_completion_queue_destroy(cc); } -static gpr_mu shutdown_mu, mu; -static gpr_cv shutdown_cv, cv; - // Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: @@ -161,11 +158,8 @@ class TagCallback : public grpc_experimental_completion_queue_functor { } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - gpr_mu_lock(&mu); GPR_ASSERT(static_cast(ok)); *static_cast(cb)->iter_ += 1; - gpr_cv_signal(&cv); - gpr_mu_unlock(&mu); }; private: @@ -180,10 +174,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); - gpr_cv_signal(&shutdown_cv); - gpr_mu_unlock(&shutdown_mu); } private: @@ -192,12 +183,8 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { TrackCounters track_counters; - int iteration = 0, current_iterations = 0; + int iteration = 0; TagCallback tag_cb(&iteration); - gpr_mu_init(&mu); - gpr_cv_init(&cv); - gpr_mu_init(&shutdown_mu); - gpr_cv_init(&shutdown_cv); bool got_shutdown = false; ShutdownCallback shutdown_cb(&got_shutdown); grpc_completion_queue* cc = @@ -211,29 +198,9 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { nullptr, &completion); } shutdown_and_destroy(cc); - - gpr_mu_lock(&mu); - current_iterations = static_cast(state.iterations()); - while (current_iterations != iteration) { - // Wait for all the callbacks to complete. - gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); - } - gpr_mu_unlock(&mu); - - gpr_mu_lock(&shutdown_mu); - while (!got_shutdown) { - // Wait for the shutdown callback to complete. - gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); - } - gpr_mu_unlock(&shutdown_mu); - GPR_ASSERT(got_shutdown); GPR_ASSERT(iteration == static_cast(state.iterations())); track_counters.Finish(state); - gpr_cv_destroy(&cv); - gpr_mu_destroy(&mu); - gpr_cv_destroy(&shutdown_cv); - gpr_mu_destroy(&shutdown_mu); } BENCHMARK(BM_Callback_CQ_Pass1Core); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 0d27e0efa50..9fb86bd8299 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -115,7 +115,7 @@ class BidiClient int msgs_size_; std::mutex mu; std::condition_variable cv; - bool done = false; + bool done; }; template From 28ccd61cf5ebab2b48301b51b98efb7743f39246 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 29 May 2019 12:21:15 -0700 Subject: [PATCH 173/676] Use SubchannelInterface to hide implementation from LB policy API. --- BUILD | 1 + BUILD.gn | 1 + build.yaml | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + package.xml | 1 + .../filters/client_channel/client_channel.cc | 123 ++++++++++++++---- .../ext/filters/client_channel/lb_policy.h | 8 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 6 +- .../lb_policy/pick_first/pick_first.cc | 10 +- .../lb_policy/round_robin/round_robin.cc | 7 +- .../lb_policy/subchannel_list.h | 91 ++++++------- .../client_channel/lb_policy/xds/xds.cc | 11 +- .../client_channel/resolving_lb_policy.cc | 5 +- .../client_channel/resolving_lb_policy.h | 3 +- .../ext/filters/client_channel/subchannel.cc | 26 +--- .../ext/filters/client_channel/subchannel.h | 46 ++----- .../client_channel/subchannel_interface.h | 109 ++++++++++++++++ test/core/util/test_lb_policies.cc | 3 +- tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 2 + 22 files changed, 302 insertions(+), 157 deletions(-) create mode 100644 src/core/ext/filters/client_channel/subchannel_interface.h diff --git a/BUILD b/BUILD index 63744760bfd..e0827d46cb1 100644 --- a/BUILD +++ b/BUILD @@ -1143,6 +1143,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_interface.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h", ], language = "c++", diff --git a/BUILD.gn b/BUILD.gn index 14e5c3f0b5f..258cdc9f873 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -345,6 +345,7 @@ config("grpc_config") { "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_interface.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.h", "src/core/ext/filters/deadline/deadline_filter.cc", diff --git a/build.yaml b/build.yaml index 529afecbb33..5c085f18787 100644 --- a/build.yaml +++ b/build.yaml @@ -595,6 +595,7 @@ filegroups: - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/service_config.h - src/core/ext/filters/client_channel/subchannel.h + - src/core/ext/filters/client_channel/subchannel_interface.h - src/core/ext/filters/client_channel/subchannel_pool_interface.h src: - src/core/ext/filters/client_channel/backup_poller.cc diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0ce31532629..3b463cf7b90 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -399,6 +399,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', + 'src/core/ext/filters/client_channel/subchannel_interface.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8ad00aad096..85add8fb7a2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -371,6 +371,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', + 'src/core/ext/filters/client_channel/subchannel_interface.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', @@ -1023,6 +1024,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', + 'src/core/ext/filters/client_channel/subchannel_interface.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0bbf10fb361..e9d215bf10f 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -305,6 +305,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_interface.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) diff --git a/package.xml b/package.xml index eca74c8f167..fd712698a62 100644 --- a/package.xml +++ b/package.xml @@ -310,6 +310,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 5717d3e66d2..6b6045c98f6 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -51,6 +51,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" @@ -174,6 +175,7 @@ class ChannelData { private: class ConnectivityStateAndPickerSetter; class ServiceConfigSetter; + class GrpcSubchannel; class ClientChannelControlHelper; class ExternalConnectivityWatcher { @@ -221,7 +223,7 @@ class ChannelData { ~ChannelData(); static bool ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error); @@ -270,6 +272,7 @@ class ChannelData { OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; + UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; bool received_first_resolver_result_ = false; @@ -954,6 +957,65 @@ void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( &self->chand_->state_tracker_, self->state_, &self->my_closure_); } +// +// ChannelData::GrpcSubchannel +// + +// This class is a wrapper for Subchannel that hides details of the +// channel's implementation (such as the health check service name) from +// the LB policy API. +// +// Note that no synchronization is needed here, because even if the +// underlying subchannel is shared between channels, this wrapper will only +// be used within one channel, so it will always be synchronized by the +// control plane combiner. +class ChannelData::GrpcSubchannel : public SubchannelInterface { + public: + GrpcSubchannel(Subchannel* subchannel, + UniquePtr health_check_service_name) + : subchannel_(subchannel), + health_check_service_name_(std::move(health_check_service_name)) {} + + ~GrpcSubchannel() { GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); } + + grpc_connectivity_state CheckConnectivityState( + RefCountedPtr* connected_subchannel) + override { + RefCountedPtr tmp; + auto retval = subchannel_->CheckConnectivityState( + health_check_service_name_.get(), &tmp); + *connected_subchannel = std::move(tmp); + return retval; + } + + void WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr watcher) override { + subchannel_->WatchConnectivityState( + initial_state, + UniquePtr(gpr_strdup(health_check_service_name_.get())), + std::move(watcher)); + } + + void CancelConnectivityStateWatch( + ConnectivityStateWatcher* watcher) override { + subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(), + watcher); + } + + void AttemptToConnect() override { subchannel_->AttemptToConnect(); } + + channelz::SubchannelNode* channelz_node() override { + return subchannel_->channelz_node(); + } + + void ResetBackoff() override { subchannel_->ResetBackoff(); } + + private: + Subchannel* subchannel_; + UniquePtr health_check_service_name_; +}; + // // ChannelData::ClientChannelControlHelper // @@ -970,15 +1032,26 @@ class ChannelData::ClientChannelControlHelper "ClientChannelControlHelper"); } - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override { + bool inhibit_health_checking = grpc_channel_arg_get_bool( + grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); + UniquePtr health_check_service_name; + if (!inhibit_health_checking) { + health_check_service_name.reset( + gpr_strdup(chand_->health_check_service_name_.get())); + } + static const char* args_to_remove[] = {GRPC_ARG_INHIBIT_HEALTH_CHECKING}; grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &arg, 1); + grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( + &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &arg, 1); Subchannel* subchannel = chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); - return subchannel; + if (subchannel == nullptr) return nullptr; + return MakeRefCounted(subchannel, + std::move(health_check_service_name)); } grpc_channel* CreateChannel(const char* target, @@ -1211,14 +1284,14 @@ void ChannelData::ProcessLbPolicy( // Synchronous callback from ResolvingLoadBalancingPolicy to process a // resolver result update. bool ChannelData::ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error) { ChannelData* chand = static_cast(arg); RefCountedPtr service_config; // If resolver did not return a service config or returned an invalid service // config, we need a fallback service config. - if (result->service_config_error != GRPC_ERROR_NONE) { + if (result.service_config_error != GRPC_ERROR_NONE) { // If the service config was invalid, then fallback to the saved service // config. If there is no saved config either, use the default service // config. @@ -1239,7 +1312,7 @@ bool ChannelData::ProcessResolverResultLocked( } service_config = chand->default_service_config_; } - } else if (result->service_config == nullptr) { + } else if (result.service_config == nullptr) { if (chand->default_service_config_ != nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, @@ -1250,11 +1323,11 @@ bool ChannelData::ProcessResolverResultLocked( service_config = chand->default_service_config_; } } else { - service_config = result->service_config; + service_config = result.service_config; } - *service_config_error = GRPC_ERROR_REF(result->service_config_error); + *service_config_error = GRPC_ERROR_REF(result.service_config_error); if (service_config == nullptr && - result->service_config_error != GRPC_ERROR_NONE) { + result.service_config_error != GRPC_ERROR_NONE) { return false; } // Process service config. @@ -1267,19 +1340,6 @@ bool ChannelData::ProcessResolverResultLocked( service_config->GetGlobalParsedConfig( internal::ClientChannelServiceConfigParser::ParserIndex())); } - // TODO(roth): Eliminate this hack as part of hiding health check - // service name from LB policy API. As part of this, change the API - // for this function to pass in result as a const reference. - if (parsed_service_config != nullptr && - parsed_service_config->health_check_service_name() != nullptr) { - grpc_arg new_arg = grpc_channel_arg_string_create( - const_cast("grpc.temp.health_check"), - const_cast(parsed_service_config->health_check_service_name())); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(result->args, &new_arg, 1); - grpc_channel_args_destroy(result->args); - result->args = new_args; - } // Check if the config has changed. const bool service_config_changed = ((service_config == nullptr) != @@ -1296,6 +1356,14 @@ bool ChannelData::ProcessResolverResultLocked( "chand=%p: resolver returned updated service config: \"%s\"", chand, service_config_json.get()); } + // Save health check service name. + if (service_config != nullptr) { + chand->health_check_service_name_.reset( + gpr_strdup(parsed_service_config->health_check_service_name())); + } else { + chand->health_check_service_name_.reset(); + } + // Save service config. chand->saved_service_config_ = std::move(service_config); } // We want to set the service config at least once. This should not really be @@ -1314,7 +1382,7 @@ bool ChannelData::ProcessResolverResultLocked( chand->saved_service_config_); } UniquePtr processed_lb_policy_name; - chand->ProcessLbPolicy(*result, parsed_service_config, + chand->ProcessLbPolicy(result, parsed_service_config, &processed_lb_policy_name, lb_policy_config); // Swap out the data used by GetChannelInfo(). { @@ -1336,8 +1404,9 @@ grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { LoadBalancingPolicy::PickResult result = picker_->Pick(LoadBalancingPolicy::PickArgs()); if (result.connected_subchannel != nullptr) { - result.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); + ConnectedSubchannel* connected_subchannel = + static_cast(result.connected_subchannel.get()); + connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); } else { if (result.error == GRPC_ERROR_NONE) { result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 5920254a9ef..2cadcc31998 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/service_config.h" -#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/client_channel/subchannel_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -128,7 +128,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Used only if type is PICK_COMPLETE. Will be set to the selected /// subchannel, or nullptr if the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; + RefCountedPtr connected_subchannel; /// Used only if type is PICK_TRANSIENT_FAILURE. /// Error to be set when returning a transient failure. @@ -184,8 +184,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) - GRPC_ABSTRACT; + virtual RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) GRPC_ABSTRACT; /// Creates a channel with the specified target and channel args. /// This can be used in cases where the LB policy needs to create a diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 2c652e4c6e6..a3a2a44eb0e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -293,7 +293,8 @@ class GrpcLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -620,7 +621,8 @@ bool GrpcLb::Helper::CalledByCurrentChild() const { return child_ == parent_->child_policy_.get(); } -Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { +RefCountedPtr GrpcLb::Helper::CreateSubchannel( + const grpc_channel_args& args) { if (parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 1b0dd230b49..4680117fede 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -68,8 +68,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel) - : SubchannelData(subchannel_list, address, subchannel) {} + const ServerAddress& address, + RefCountedPtr subchannel) + : SubchannelData(subchannel_list, address, std::move(subchannel)) {} void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state) override; @@ -112,7 +113,8 @@ class PickFirst : public LoadBalancingPolicy { class Picker : public SubchannelPicker { public: - explicit Picker(RefCountedPtr connected_subchannel) + explicit Picker( + RefCountedPtr connected_subchannel) : connected_subchannel_(std::move(connected_subchannel)) {} PickResult Pick(PickArgs args) override { @@ -123,7 +125,7 @@ class PickFirst : public LoadBalancingPolicy { } private: - RefCountedPtr connected_subchannel_; + RefCountedPtr connected_subchannel_; }; // Helper class to ensure that any function that modifies the child refs diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 0b9915de28e..3b8ec4f2872 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -83,8 +83,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel) - : SubchannelData(subchannel_list, address, subchannel) {} + const ServerAddress& address, + RefCountedPtr subchannel) + : SubchannelData(subchannel_list, address, std::move(subchannel)) {} grpc_connectivity_state connectivity_state() const { return last_connectivity_state_; @@ -156,7 +157,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobin* parent_; size_t last_picked_index_; - InlinedVector, 10> subchannels_; + InlinedVector, 10> subchannels_; }; // Helper class to ensure that any function that modifies the child refs diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 93b4bbd369a..8929bc4ab1e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -27,7 +27,10 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" +// TODO(roth): Should not need the include of subchannel.h here, since +// that implementation should be hidden from the LB policy API. #include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/client_channel/subchannel_interface.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/abstract.h" @@ -88,11 +91,11 @@ class SubchannelData { } // Returns a pointer to the subchannel. - Subchannel* subchannel() const { return subchannel_; } + SubchannelInterface* subchannel() const { return subchannel_.get(); } // Returns the connected subchannel. Will be null if the subchannel // is not connected. - ConnectedSubchannel* connected_subchannel() const { + ConnectedSubchannelInterface* connected_subchannel() const { return connected_subchannel_.get(); } @@ -102,8 +105,8 @@ class SubchannelData { // calling CancelConnectivityWatchLocked()). grpc_connectivity_state CheckConnectivityStateLocked() { GPR_ASSERT(pending_watcher_ == nullptr); - connectivity_state_ = subchannel()->CheckConnectivityState( - subchannel_list_->health_check_service_name(), &connected_subchannel_); + connectivity_state_ = + subchannel()->CheckConnectivityState(&connected_subchannel_); return connectivity_state_; } @@ -128,7 +131,8 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel); + const ServerAddress& address, + RefCountedPtr subchannel); virtual ~SubchannelData(); @@ -140,7 +144,7 @@ class SubchannelData { private: // Watcher for subchannel connectivity state. - class Watcher : public Subchannel::ConnectivityStateWatcher { + class Watcher : public SubchannelInterface::ConnectivityStateWatcher { public: Watcher( SubchannelData* subchannel_data, @@ -150,9 +154,9 @@ class SubchannelData { ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } - void OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) override; + void OnConnectivityStateChange(grpc_connectivity_state new_state, + RefCountedPtr + connected_subchannel) override; grpc_pollset_set* interested_parties() override { return subchannel_list_->policy()->interested_parties(); @@ -169,7 +173,7 @@ class SubchannelData { RefCountedPtr> subchannel_list, grpc_connectivity_state state, - RefCountedPtr connected_subchannel); + RefCountedPtr connected_subchannel); ~Updater() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor"); @@ -182,7 +186,7 @@ class SubchannelData { RefCountedPtr> subchannel_list_; const grpc_connectivity_state state_; - RefCountedPtr connected_subchannel_; + RefCountedPtr connected_subchannel_; grpc_closure closure_; }; @@ -196,12 +200,12 @@ class SubchannelData { // Backpointer to owning subchannel list. Not owned. SubchannelList* subchannel_list_; // The subchannel. - Subchannel* subchannel_; + RefCountedPtr subchannel_; // Will be non-null when the subchannel's state is being watched. - Subchannel::ConnectivityStateWatcher* pending_watcher_ = nullptr; + SubchannelInterface::ConnectivityStateWatcher* pending_watcher_ = nullptr; // Data updated by the watcher. grpc_connectivity_state connectivity_state_; - RefCountedPtr connected_subchannel_; + RefCountedPtr connected_subchannel_; }; // A list of subchannels. @@ -235,9 +239,6 @@ class SubchannelList : public InternallyRefCounted { // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } - const char* health_check_service_name() const { - return health_check_service_name_.get(); - } // Resets connection backoff of all subchannels. // TODO(roth): We will probably need to rethink this as part of moving @@ -275,8 +276,6 @@ class SubchannelList : public InternallyRefCounted { TraceFlag* tracer_; - UniquePtr health_check_service_name_; - grpc_combiner* combiner_; // The list of subchannels. @@ -300,7 +299,7 @@ template void SubchannelData::Watcher:: OnConnectivityStateChange( grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) { + RefCountedPtr connected_subchannel) { // Will delete itself. New(subchannel_data_, subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"), @@ -314,7 +313,7 @@ SubchannelData::Watcher::Updater:: RefCountedPtr> subchannel_list, grpc_connectivity_state state, - RefCountedPtr connected_subchannel) + RefCountedPtr connected_subchannel) : subchannel_data_(subchannel_data), subchannel_list_(std::move(subchannel_list)), state_(state), @@ -336,7 +335,7 @@ void SubchannelData::Watcher::Updater:: "connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", sd->subchannel_list_->tracer()->name(), sd->subchannel_list_->policy(), sd->subchannel_list_, sd->Index(), - sd->subchannel_list_->num_subchannels(), sd->subchannel_, + sd->subchannel_list_->num_subchannels(), sd->subchannel_.get(), grpc_connectivity_state_name(self->state_), self->connected_subchannel_.get(), sd->subchannel_list_->shutting_down(), sd->pending_watcher_); @@ -360,9 +359,9 @@ void SubchannelData::Watcher::Updater:: template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel) + const ServerAddress& address, RefCountedPtr subchannel) : subchannel_list_(subchannel_list), - subchannel_(subchannel), + subchannel_(std::move(subchannel)), // We assume that the current state is IDLE. If not, we'll get a // callback telling us that. connectivity_state_(GRPC_CHANNEL_IDLE) {} @@ -382,10 +381,9 @@ void SubchannelData:: " (subchannel %p): unreffing subchannel", subchannel_list_->tracer()->name(), subchannel_list_->policy(), subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_); + subchannel_.get()); } - GRPC_SUBCHANNEL_UNREF(subchannel_, reason); - subchannel_ = nullptr; + subchannel_.reset(); connected_subchannel_.reset(); } } @@ -407,16 +405,16 @@ void SubchannelDatatracer()->name(), subchannel_list_->policy(), subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_, grpc_connectivity_state_name(connectivity_state_)); + subchannel_.get(), + grpc_connectivity_state_name(connectivity_state_)); } GPR_ASSERT(pending_watcher_ == nullptr); pending_watcher_ = New(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); subchannel_->WatchConnectivityState( connectivity_state_, - UniquePtr( - gpr_strdup(subchannel_list_->health_check_service_name())), - UniquePtr(pending_watcher_)); + UniquePtr( + pending_watcher_)); } template @@ -428,11 +426,10 @@ void SubchannelData:: " (subchannel %p): canceling connectivity watch (%s)", subchannel_list_->tracer()->name(), subchannel_list_->policy(), subchannel_list_, Index(), subchannel_list_->num_subchannels(), - subchannel_, reason); + subchannel_.get(), reason); } if (pending_watcher_ != nullptr) { - subchannel_->CancelConnectivityStateWatch( - subchannel_list_->health_check_service_name(), pending_watcher_); + subchannel_->CancelConnectivityStateWatch(pending_watcher_); pending_watcher_ = nullptr; } } @@ -463,25 +460,12 @@ SubchannelList::SubchannelList( tracer_->name(), policy, this, addresses.size()); } subchannels_.reserve(addresses.size()); - // Find health check service name. - const bool inhibit_health_checking = grpc_channel_arg_get_bool( - grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); - if (!inhibit_health_checking) { - const char* health_check_service_name = grpc_channel_arg_get_string( - grpc_channel_args_find(&args, "grpc.temp.health_check")); - if (health_check_service_name != nullptr) { - health_check_service_name_.reset(gpr_strdup(health_check_service_name)); - } - } // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. - // We also remove the health-checking-related args, since we are - // handling that here. // We remove the service config, since it will be passed into the // subchannel via call context. - static const char* keys_to_remove[] = { - GRPC_ARG_SUBCHANNEL_ADDRESS, "grpc.temp.health_check", - GRPC_ARG_INHIBIT_HEALTH_CHECKING, GRPC_ARG_SERVICE_CONFIG}; + static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, + GRPC_ARG_SERVICE_CONFIG}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { // TODO(roth): we should ideally hide this from the LB policy code. In @@ -504,7 +488,8 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = helper->CreateSubchannel(*new_args); + RefCountedPtr subchannel = + helper->CreateSubchannel(*new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. @@ -523,11 +508,11 @@ SubchannelList::SubchannelList( gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR ": Created subchannel %p for address uri %s", - tracer_->name(), policy_, this, subchannels_.size(), subchannel, - address_uri); + tracer_->name(), policy_, this, subchannels_.size(), + subchannel.get(), address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(this, addresses[i], subchannel); + subchannels_.emplace_back(this, addresses[i], std::move(subchannel)); } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index d70042af229..b198e0e8637 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -334,7 +334,8 @@ class XdsLb : public LoadBalancingPolicy { explicit FallbackHelper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -374,7 +375,8 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -579,7 +581,7 @@ bool XdsLb::FallbackHelper::CalledByCurrentFallback() const { return child_ == parent_->fallback_policy_.get(); } -Subchannel* XdsLb::FallbackHelper::CreateSubchannel( +RefCountedPtr XdsLb::FallbackHelper::CreateSubchannel( const grpc_channel_args& args) { if (parent_->shutting_down_ || (!CalledByPendingFallback() && !CalledByCurrentFallback())) { @@ -1997,7 +1999,8 @@ bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { return child_ == entry_->child_policy_.get(); } -Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( +RefCountedPtr +XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( const grpc_channel_args& args) { if (entry_->parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 3fe2ee74c92..d23ac1f4e33 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -106,7 +106,8 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; return parent_->channel_control_helper()->CreateSubchannel(args); @@ -536,7 +537,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( if (process_resolver_result_ != nullptr) { grpc_error* service_config_error = GRPC_ERROR_NONE; service_config_changed = process_resolver_result_( - process_resolver_result_user_data_, &result, &lb_policy_name, + process_resolver_result_user_data_, result, &lb_policy_name, &lb_policy_config, &service_config_error); if (service_config_error != GRPC_ERROR_NONE) { service_config_error_string = diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index cc9f3176cce..679c8d0fba0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -69,7 +69,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // empty, it means that we don't have a valid service config to use, and we // should set the channel to be in TRANSIENT_FAILURE. typedef bool (*ProcessResolverResultCallback)( - void* user_data, Resolver::Result* result, const char** lb_policy_name, + void* user_data, const Resolver::Result& result, + const char** lb_policy_name, RefCountedPtr* lb_policy_config, grpc_error** service_config_error); // If error is set when this returns, then construction failed, and diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index cd778976166..cc3457e1e96 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -83,7 +83,7 @@ ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, RefCountedPtr channelz_subchannel, intptr_t socket_uuid) - : RefCounted(&grpc_trace_stream_refcount), + : ConnectedSubchannelInterface(&grpc_trace_stream_refcount), channel_stack_(channel_stack), args_(grpc_channel_args_copy(args)), channelz_subchannel_(std::move(channelz_subchannel)), @@ -376,25 +376,17 @@ class Subchannel::ConnectedSubchannelStateWatcher { void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( UniquePtr watcher) { - watcher->next_ = head_; - head_ = watcher.release(); + watchers_.insert(MakePair(watcher.get(), std::move(watcher))); } void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( ConnectivityStateWatcher* watcher) { - for (ConnectivityStateWatcher** w = &head_; *w != nullptr; w = &(*w)->next_) { - if (*w == watcher) { - *w = watcher->next_; - Delete(watcher); - return; - } - } - GPR_UNREACHABLE_CODE(return ); + watchers_.erase(watcher); } void Subchannel::ConnectivityStateWatcherList::NotifyLocked( Subchannel* subchannel, grpc_connectivity_state state) { - for (ConnectivityStateWatcher* w = head_; w != nullptr; w = w->next_) { + for (const auto& p : watchers_) { RefCountedPtr connected_subchannel; if (state == GRPC_CHANNEL_READY) { connected_subchannel = subchannel->connected_subchannel_; @@ -407,15 +399,7 @@ void Subchannel::ConnectivityStateWatcherList::NotifyLocked( // the notification into the client_channel control-plane combiner // before processing it. But if we ever have any other callers here, // we will probably need to change this. - w->OnConnectivityStateChange(state, std::move(connected_subchannel)); - } -} - -void Subchannel::ConnectivityStateWatcherList::Clear() { - while (head_ != nullptr) { - ConnectivityStateWatcher* next = head_->next_; - Delete(head_); - head_ = next; + p.second->OnConnectivityStateChange(state, std::move(connected_subchannel)); } } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index e0741bb28fa..2f05792b872 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/subchannel_interface.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" @@ -69,7 +70,7 @@ namespace grpc_core { class SubchannelCall; -class ConnectedSubchannel : public RefCounted { +class ConnectedSubchannel : public ConnectedSubchannelInterface { public: struct CallArgs { grpc_polling_entity* pollent; @@ -96,7 +97,7 @@ class ConnectedSubchannel : public RefCounted { grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } - const grpc_channel_args* args() const { return args_; } + const grpc_channel_args* args() const override { return args_; } channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } @@ -176,37 +177,9 @@ class SubchannelCall { // A subchannel that knows how to connect to exactly one target address. It // provides a target for load balancing. class Subchannel { - private: - class ConnectivityStateWatcherList; // Forward declaration. - public: - class ConnectivityStateWatcher { - public: - virtual ~ConnectivityStateWatcher() = default; - - // Will be invoked whenever the subchannel's connectivity state - // changes. There will be only one invocation of this method on a - // given watcher instance at any given time. - // - // When the state changes to READY, connected_subchannel will - // contain a ref to the connected subchannel. When it changes from - // READY to some other state, the implementation must release its - // ref to the connected subchannel. - virtual void OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) // NOLINT - GRPC_ABSTRACT; - - virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS - - private: - // For access to next_. - friend class Subchannel::ConnectivityStateWatcherList; - - ConnectivityStateWatcher* next_ = nullptr; - }; + typedef SubchannelInterface::ConnectivityStateWatcher + ConnectivityStateWatcher; // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, @@ -296,12 +269,15 @@ class Subchannel { // Notifies all watchers in the list about a change to state. void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); - void Clear(); + void Clear() { watchers_.clear(); } - bool empty() const { return head_ == nullptr; } + bool empty() const { return watchers_.empty(); } private: - ConnectivityStateWatcher* head_ = nullptr; + // TODO(roth): This could be a set instead of a map if we had a set + // implementation. + Map> + watchers_; }; // A map that tracks ConnectivityStateWatchers using a particular health diff --git a/src/core/ext/filters/client_channel/subchannel_interface.h b/src/core/ext/filters/client_channel/subchannel_interface.h new file mode 100644 index 00000000000..0a471045f03 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_interface.h @@ -0,0 +1,109 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H + +#include + +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" + +namespace grpc_core { + +// TODO(roth): In a subsequent PR, remove this from this API. +class ConnectedSubchannelInterface + : public RefCounted { + public: + virtual const grpc_channel_args* args() const GRPC_ABSTRACT; + + protected: + template + explicit ConnectedSubchannelInterface(TraceFlagT* trace_flag = nullptr) + : RefCounted(trace_flag) {} +}; + +class SubchannelInterface : public RefCounted { + public: + class ConnectivityStateWatcher { + public: + virtual ~ConnectivityStateWatcher() = default; + + // Will be invoked whenever the subchannel's connectivity state + // changes. There will be only one invocation of this method on a + // given watcher instance at any given time. + // + // When the state changes to READY, connected_subchannel will + // contain a ref to the connected subchannel. When it changes from + // READY to some other state, the implementation must release its + // ref to the connected subchannel. + virtual void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr + connected_subchannel) // NOLINT + GRPC_ABSTRACT; + + // TODO(roth): Remove this as soon as we move to EventManager-based + // polling. + virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + virtual ~SubchannelInterface() = default; + + // Returns the current connectivity state of the subchannel. + virtual grpc_connectivity_state CheckConnectivityState( + RefCountedPtr* connected_subchannel) + GRPC_ABSTRACT; + + // Starts watching the subchannel's connectivity state. + // The first callback to the watcher will be delivered when the + // subchannel's connectivity state becomes a value other than + // initial_state, which may happen immediately. + // Subsequent callbacks will be delivered as the subchannel's state + // changes. + // The watcher will be destroyed either when the subchannel is + // destroyed or when CancelConnectivityStateWatch() is called. + // There can be only one watcher of a given subchannel. It is not + // valid to call this method a second time without first cancelling + // the previous watcher using CancelConnectivityStateWatch(). + virtual void WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr watcher) GRPC_ABSTRACT; + + // Cancels a connectivity state watch. + // If the watcher has already been destroyed, this is a no-op. + virtual void CancelConnectivityStateWatch(ConnectivityStateWatcher* watcher) + GRPC_ABSTRACT; + + // Attempt to connect to the backend. Has no effect if already connected. + virtual void AttemptToConnect() GRPC_ABSTRACT; + + // TODO(roth): These methods should be removed from this interface to + // bettter hide grpc-specific functionality from the LB policy API. + virtual channelz::SubchannelNode* channelz_node() GRPC_ABSTRACT; + virtual void ResetBackoff() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INTERFACE_H */ diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index bd28422bcd1..ced6d9d8027 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -143,7 +143,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy InterceptRecvTrailingMetadataCallback cb, void* user_data) : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + RefCountedPtr CreateSubchannel( + const grpc_channel_args& args) override { return parent_->channel_control_helper()->CreateSubchannel(args); } diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 2c20d69e6e3..7768bca30f5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -974,6 +974,7 @@ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ +src/core/ext/filters/client_channel/subchannel_interface.h \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.h \ src/core/ext/filters/deadline/deadline_filter.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a9dc9fcfe3f..a479a00509a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8912,6 +8912,7 @@ "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_interface.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, @@ -8968,6 +8969,7 @@ "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_interface.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], From 196b0aa3a3a249dc1edc38a9ca6c035e9ab4ddf8 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 29 May 2019 13:15:47 -0700 Subject: [PATCH 174/676] Revert "Revert "Start supporting a callback-based RPC under lock"" --- src/core/lib/surface/completion_queue.cc | 85 +++++++++++-------- src/core/lib/surface/completion_queue.h | 3 +- src/core/lib/surface/server.cc | 2 +- test/core/surface/completion_queue_test.cc | 44 +++++++++- .../end2end/client_callback_end2end_test.cc | 28 ++++++ test/cpp/microbenchmarks/bm_cq.cc | 35 +++++++- .../callback_streaming_ping_pong.h | 2 +- 7 files changed, 157 insertions(+), 42 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index e796071eedc..d0ed1a9f673 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -34,6 +34,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" @@ -200,7 +201,7 @@ struct cq_vtable { bool (*begin_op)(grpc_completion_queue* cq, void* tag); void (*end_op)(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, bool internal); grpc_event (*next)(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, @@ -354,23 +355,20 @@ static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); // queue. The done argument is a callback that will be invoked when it is // safe to free up that storage. The storage MUST NOT be freed until the // done callback is invoked. -static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); - -static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); - -static void cq_end_op_for_callback(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); +static void cq_end_op_for_next( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal); + +static void cq_end_op_for_pluck( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal); + +static void cq_end_op_for_callback( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal); static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); @@ -674,11 +672,10 @@ bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_NEXT) */ -static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { +static void cq_end_op_for_next( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_next", 0); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || @@ -754,11 +751,10 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a * completion * type of GRPC_CQ_PLUCK) */ -static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, - grpc_error* error, - void (*done)(void* done_arg, - grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { +static void cq_end_op_for_pluck( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_pluck", 0); cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); @@ -821,15 +817,19 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, GRPC_ERROR_UNREF(error); } +static void functor_callback(void* arg, grpc_error* error) { + auto* functor = static_cast(arg); + functor->functor_run(functor, error == GRPC_ERROR_NONE); +} + /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ static void cq_end_op_for_callback( grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, - grpc_cq_completion* storage) { + grpc_cq_completion* storage, bool internal) { GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); - bool is_success = (error == GRPC_ERROR_NONE); if (GRPC_TRACE_FLAG_ENABLED(grpc_api_trace) || (GRPC_TRACE_FLAG_ENABLED(grpc_trace_operation_failures) && @@ -856,16 +856,25 @@ static void cq_end_op_for_callback( cq_finish_shutdown_callback(cq); } - GRPC_ERROR_UNREF(error); - auto* functor = static_cast(tag); - grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, is_success); + if (internal) { + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, + (error == GRPC_ERROR_NONE)); + } else { + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage) { - cq->vtable->end_op(cq, tag, error, done, done_arg, storage); + void* done_arg, grpc_cq_completion* storage, + bool internal) { + cq->vtable->end_op(cq, tag, error, done, done_arg, storage, internal); } typedef struct { @@ -1343,7 +1352,11 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, callback, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index d60fe6d6efe..3ba9fbb8765 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -77,7 +77,8 @@ bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag); grpc_cq_begin_op */ void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), - void* done_arg, grpc_cq_completion* storage); + void* done_arg, grpc_cq_completion* storage, + bool internal = false); grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5ecd5662c2c..44de0cd42dd 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -513,7 +513,7 @@ static void publish_call(grpc_server* server, call_data* calld, size_t cq_idx, } grpc_cq_end_op(calld->cq_new, rc->tag, GRPC_ERROR_NONE, done_request_event, - rc, &rc->completion); + rc, &rc->completion, true); } static void publish_new_rpc(void* arg, grpc_error* error) { diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 7c3630eaf18..4a33b934f43 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -23,6 +23,7 @@ #include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -359,12 +360,19 @@ static void test_pluck_after_shutdown(void) { static void test_callback(void) { grpc_completion_queue* cc; - void* tags[128]; + static void* tags[128]; grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; grpc_cq_polling_type polling_types[] = { GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING}; grpc_completion_queue_attributes attr; unsigned i; + static gpr_mu mu, shutdown_mu; + static gpr_cv cv, shutdown_cv; + static int cb_counter; + gpr_mu_init(&mu); + gpr_mu_init(&shutdown_mu); + gpr_cv_init(&cv); + gpr_cv_init(&shutdown_cv); LOG_TEST("test_callback"); @@ -376,7 +384,11 @@ static void test_callback(void) { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); + // Signal when the shutdown callback is completed. + gpr_cv_signal(&shutdown_cv); + gpr_mu_unlock(&shutdown_mu); } private: @@ -391,9 +403,9 @@ static void test_callback(void) { for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { int sumtags = 0; int counter = 0; + cb_counter = 0; { // reset exec_ctx types - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; attr.cq_polling_type = polling_types[pidx]; cc = grpc_completion_queue_create( @@ -409,7 +421,13 @@ static void test_callback(void) { int ok) { GPR_ASSERT(static_cast(ok)); auto* callback = static_cast(cb); + gpr_mu_lock(&mu); + cb_counter++; *callback->counter_ += callback->tag_; + if (cb_counter == GPR_ARRAY_SIZE(tags)) { + gpr_cv_signal(&cv); + } + gpr_mu_unlock(&mu); grpc_core::Delete(callback); }; @@ -429,12 +447,34 @@ static void test_callback(void) { nullptr, &completions[i]); } + gpr_mu_lock(&mu); + while (cb_counter != GPR_ARRAY_SIZE(tags)) { + // Wait for all the callbacks to complete. + gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&mu); + shutdown_and_destroy(cc); + + gpr_mu_lock(&shutdown_mu); + while (!got_shutdown) { + // Wait for the shutdown callback to complete. + gpr_cv_wait(&shutdown_cv, &shutdown_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&shutdown_mu); } + + // Run the assertions to check if the test ran successfully. GPR_ASSERT(sumtags == counter); GPR_ASSERT(got_shutdown); got_shutdown = false; } + + gpr_cv_destroy(&cv); + gpr_cv_destroy(&shutdown_cv); + gpr_mu_destroy(&mu); + gpr_mu_destroy(&shutdown_mu); } struct thread_state { diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a154324216b..8cf6def1073 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -374,6 +374,34 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { SendRpcs(1, false); } +TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { + MAYBE_SKIP_TEST; + ResetStub(); + std::mutex mu; + std::condition_variable cv; + bool done = false; + EchoRequest request; + request.set_message("Hello locked world."); + EchoResponse response; + ClientContext cli_ctx; + { + std::lock_guard l(mu); + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&mu, &cv, &done, &request, &response](Status s) { + std::lock_guard l(mu); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(request.message(), response.message()); + done = true; + cv.notify_one(); + }); + } + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { MAYBE_SKIP_TEST; ResetStub(); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index 50eb9454fbe..edbff9c2be3 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -150,6 +150,9 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { grpc_completion_queue_destroy(cc); } +static gpr_mu shutdown_mu, mu; +static gpr_cv shutdown_cv, cv; + // Tag completion queue iterate times class TagCallback : public grpc_experimental_completion_queue_functor { public: @@ -158,8 +161,11 @@ class TagCallback : public grpc_experimental_completion_queue_functor { } ~TagCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&mu); GPR_ASSERT(static_cast(ok)); *static_cast(cb)->iter_ += 1; + gpr_cv_signal(&cv); + gpr_mu_unlock(&mu); }; private: @@ -174,7 +180,10 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } ~ShutdownCallback() {} static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + gpr_mu_lock(&shutdown_mu); *static_cast(cb)->done_ = static_cast(ok); + gpr_cv_signal(&shutdown_cv); + gpr_mu_unlock(&shutdown_mu); } private: @@ -183,8 +192,12 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { TrackCounters track_counters; - int iteration = 0; + int iteration = 0, current_iterations = 0; TagCallback tag_cb(&iteration); + gpr_mu_init(&mu); + gpr_cv_init(&cv); + gpr_mu_init(&shutdown_mu); + gpr_cv_init(&shutdown_cv); bool got_shutdown = false; ShutdownCallback shutdown_cb(&got_shutdown); grpc_completion_queue* cc = @@ -198,9 +211,29 @@ static void BM_Callback_CQ_Pass1Core(benchmark::State& state) { nullptr, &completion); } shutdown_and_destroy(cc); + + gpr_mu_lock(&mu); + current_iterations = static_cast(state.iterations()); + while (current_iterations != iteration) { + // Wait for all the callbacks to complete. + gpr_cv_wait(&cv, &mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&mu); + + gpr_mu_lock(&shutdown_mu); + while (!got_shutdown) { + // Wait for the shutdown callback to complete. + gpr_cv_wait(&shutdown_cv, &shutdown_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&shutdown_mu); + GPR_ASSERT(got_shutdown); GPR_ASSERT(iteration == static_cast(state.iterations())); track_counters.Finish(state); + gpr_cv_destroy(&cv); + gpr_mu_destroy(&mu); + gpr_cv_destroy(&shutdown_cv); + gpr_mu_destroy(&shutdown_mu); } BENCHMARK(BM_Callback_CQ_Pass1Core); diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index 9fb86bd8299..0d27e0efa50 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -115,7 +115,7 @@ class BidiClient int msgs_size_; std::mutex mu; std::condition_variable cv; - bool done; + bool done = false; }; template From bd97b1361df0a2d7ac0bbd02a2a7e618fab299cc Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 29 May 2019 12:04:40 -0700 Subject: [PATCH 175/676] Delete wrapper in executor thread to avoid self-joining deadlock --- src/cpp/client/secure_credentials.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 2d041a28664..3d2a123180b 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -22,6 +22,7 @@ #include #include #include +#include "src/core/lib/iomgr/executor.h" #include "src/core/lib/security/transport/auth_filters.h" #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" @@ -224,13 +225,23 @@ std::shared_ptr MetadataCredentialsFromPlugin( } // namespace grpc_impl namespace grpc { - -void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { - if (wrapper == nullptr) return; +namespace { +void DeleteWrapper(void* wrapper, grpc_error* ignored) { MetadataCredentialsPluginWrapper* w = static_cast(wrapper); delete w; } +} // namespace + +void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { + if (wrapper == nullptr) return; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + GRPC_CLOSURE_RUN(GRPC_CLOSURE_CREATE(DeleteWrapper, wrapper, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::SHORT)), + GRPC_ERROR_NONE); +} int MetadataCredentialsPluginWrapper::GetMetadata( void* wrapper, grpc_auth_metadata_context context, From 8ef2152c801a4210c6e630012095af5b1fd7edee Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 29 May 2019 14:28:56 -0700 Subject: [PATCH 176/676] Fix the memory leak. --- src/core/lib/surface/completion_queue.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index d0ed1a9f673..9b30b3998a5 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -820,6 +820,7 @@ static void cq_end_op_for_pluck( static void functor_callback(void* arg, grpc_error* error) { auto* functor = static_cast(arg); functor->functor_run(functor, error == GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); } /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ @@ -860,14 +861,14 @@ static void cq_end_op_for_callback( if (internal) { grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); + GRPC_ERROR_UNREF(error); } else { GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, functor, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(error)); + error); } - GRPC_ERROR_UNREF(error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -1356,7 +1357,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GRPC_CLOSURE_CREATE( functor_callback, callback, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + GRPC_ERROR_REF(GRPC_ERROR_NONE)); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From b483c27cd040f81764e40ad2e9435fd5269e9ba3 Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Wed, 29 May 2019 16:35:24 -0700 Subject: [PATCH 177/676] Update protobuf submodule version --- third_party/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/protobuf b/third_party/protobuf index 582743bf40c..09745575a92 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 582743bf40c5d3639a70f98f183914a2c0cd0680 +Subproject commit 09745575a923640154bcf307fba8aedff47f240a From 1ddaafd677ee678f3f14c56a65cbb7783765ba73 Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Wed, 29 May 2019 16:37:10 -0700 Subject: [PATCH 178/676] Update protobuf version --- bazel/grpc_deps.bzl | 6 +-- grpc.gemspec | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- .../Grpc.IntegrationTesting/EchoMessages.cs | 45 +++++++++++++++---- templates/grpc.gemspec.template | 2 +- .../python/grpcio_tools/protoc_lib_deps.py | 4 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index a4e6509782d..08022942be0 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -127,9 +127,9 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", - sha256 = "cf9e2fb1d2cd30ec9d51ff1749045208bd641f290f64b85046485934b0e03783", - strip_prefix = "protobuf-582743bf40c5d3639a70f98f183914a2c0cd0680", - url = "https://github.com/google/protobuf/archive/582743bf40c5d3639a70f98f183914a2c0cd0680.tar.gz", + sha256 = "416212e14481cff8fd4849b1c1c1200a7f34808a54377e22d7447efdf54ad758", + strip_prefix = "protobuf-09745575a923640154bcf307fba8aedff47f240a", + url = "https://github.com/google/protobuf/archive/09745575a923640154bcf307fba8aedff47f240a.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): diff --git a/grpc.gemspec b/grpc.gemspec index 36b325f8f0d..0f66332d48f 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.7' + s.add_dependency 'google-protobuf', '~> 3.8.0' s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 6354a053965..e24afdad605 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -2,6 +2,6 @@ 1.19.1 - 3.6.1 + 3.8.0 diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs index e5af4a93e99..bbba68eeac1 100644 --- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs +++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs @@ -28,7 +28,7 @@ namespace Grpc.Testing { "DGdycGMudGVzdGluZyIyCglEZWJ1Z0luZm8SFQoNc3RhY2tfZW50cmllcxgB", "IAMoCRIOCgZkZXRhaWwYAiABKAkiUAoLRXJyb3JTdGF0dXMSDAoEY29kZRgB", "IAEoBRIVCg1lcnJvcl9tZXNzYWdlGAIgASgJEhwKFGJpbmFyeV9lcnJvcl9k", - "ZXRhaWxzGAMgASgJIv8DCg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", + "ZXRhaWxzGAMgASgJIqAECg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp", "bmUYASABKAgSHgoWY2xpZW50X2NhbmNlbF9hZnRlcl91cxgCIAEoBRIeChZz", "ZXJ2ZXJfY2FuY2VsX2FmdGVyX3VzGAMgASgFEhUKDWVjaG9fbWV0YWRhdGEY", "BCABKAgSGgoSY2hlY2tfYXV0aF9jb250ZXh0GAUgASgIEh8KF3Jlc3BvbnNl", @@ -39,18 +39,19 @@ namespace Grpc.Testing { "Zy5EZWJ1Z0luZm8SEgoKc2VydmVyX2RpZRgMIAEoCBIcChRiaW5hcnlfZXJy", "b3JfZGV0YWlscxgNIAEoCRIxCg5leHBlY3RlZF9lcnJvchgOIAEoCzIZLmdy", "cGMudGVzdGluZy5FcnJvclN0YXR1cxIXCg9zZXJ2ZXJfc2xlZXBfdXMYDyAB", - "KAUSGwoTYmFja2VuZF9jaGFubmVsX2lkeBgQIAEoBSJKCgtFY2hvUmVxdWVz", - "dBIPCgdtZXNzYWdlGAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0", - "aW5nLlJlcXVlc3RQYXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVz", - "dF9kZWFkbGluZRgBIAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAki", - "TAoMRWNob1Jlc3BvbnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiAB", - "KAsyHC5ncnBjLnRlc3RpbmcuUmVzcG9uc2VQYXJhbXNiBnByb3RvMw==")); + "KAUSGwoTYmFja2VuZF9jaGFubmVsX2lkeBgQIAEoBRIfChdlY2hvX21ldGFk", + "YXRhX2luaXRpYWxseRgRIAEoCCJKCgtFY2hvUmVxdWVzdBIPCgdtZXNzYWdl", + "GAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0aW5nLlJlcXVlc3RQ", + "YXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVzdF9kZWFkbGluZRgB", + "IAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAkiTAoMRWNob1Jlc3Bv", + "bnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiABKAsyHC5ncnBjLnRl", + "c3RpbmcuUmVzcG9uc2VQYXJhbXNCA/gBAWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.DebugInfo), global::Grpc.Testing.DebugInfo.Parser, new[]{ "StackEntries", "Detail" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ErrorStatus), global::Grpc.Testing.ErrorStatus.Parser, new[]{ "Code", "ErrorMessage", "BinaryErrorDetails" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError", "ServerSleepUs", "BackendChannelIdx" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError", "ServerSleepUs", "BackendChannelIdx", "EchoMetadataInitially" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoRequest), global::Grpc.Testing.EchoRequest.Parser, new[]{ "Message", "Param" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ResponseParams), global::Grpc.Testing.ResponseParams.Parser, new[]{ "RequestDeadline", "Host", "Peer" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoResponse), global::Grpc.Testing.EchoResponse.Parser, new[]{ "Message", "Param" }, null, null, null) @@ -441,6 +442,7 @@ namespace Grpc.Testing { expectedError_ = other.expectedError_ != null ? other.expectedError_.Clone() : null; serverSleepUs_ = other.serverSleepUs_; backendChannelIdx_ = other.backendChannelIdx_; + echoMetadataInitially_ = other.echoMetadataInitially_; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -637,6 +639,17 @@ namespace Grpc.Testing { } } + /// Field number for the "echo_metadata_initially" field. + public const int EchoMetadataInitiallyFieldNumber = 17; + private bool echoMetadataInitially_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool EchoMetadataInitially { + get { return echoMetadataInitially_; } + set { + echoMetadataInitially_ = value; + } + } + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as RequestParams); @@ -666,6 +679,7 @@ namespace Grpc.Testing { if (!object.Equals(ExpectedError, other.ExpectedError)) return false; if (ServerSleepUs != other.ServerSleepUs) return false; if (BackendChannelIdx != other.BackendChannelIdx) return false; + if (EchoMetadataInitially != other.EchoMetadataInitially) return false; return Equals(_unknownFields, other._unknownFields); } @@ -688,6 +702,7 @@ namespace Grpc.Testing { if (expectedError_ != null) hash ^= ExpectedError.GetHashCode(); if (ServerSleepUs != 0) hash ^= ServerSleepUs.GetHashCode(); if (BackendChannelIdx != 0) hash ^= BackendChannelIdx.GetHashCode(); + if (EchoMetadataInitially != false) hash ^= EchoMetadataInitially.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -765,6 +780,10 @@ namespace Grpc.Testing { output.WriteRawTag(128, 1); output.WriteInt32(BackendChannelIdx); } + if (EchoMetadataInitially != false) { + output.WriteRawTag(136, 1); + output.WriteBool(EchoMetadataInitially); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -821,6 +840,9 @@ namespace Grpc.Testing { if (BackendChannelIdx != 0) { size += 2 + pb::CodedOutputStream.ComputeInt32Size(BackendChannelIdx); } + if (EchoMetadataInitially != false) { + size += 2 + 1; + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -886,6 +908,9 @@ namespace Grpc.Testing { if (other.BackendChannelIdx != 0) { BackendChannelIdx = other.BackendChannelIdx; } + if (other.EchoMetadataInitially != false) { + EchoMetadataInitially = other.EchoMetadataInitially; + } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -967,6 +992,10 @@ namespace Grpc.Testing { BackendChannelIdx = input.ReadInt32(); break; } + case 136: { + EchoMetadataInitially = input.ReadBool(); + break; + } } } } diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index d2b54a9c2f5..9ca797fe913 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -31,7 +31,7 @@ s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.7' + s.add_dependency 'google-protobuf', '~> 3.8.0' s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index e7e4ba307ec..3eef24f7075 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -14,10 +14,10 @@ # limitations under the License. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arena.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/parse_context.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/io_win32.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arena.cc', 'google/protobuf/any_lite.cc'] PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto'] CC_INCLUDE='third_party/protobuf/src' PROTO_INCLUDE='third_party/protobuf/src' -PROTOBUF_SUBMODULE_VERSION="582743bf40c5d3639a70f98f183914a2c0cd0680" +PROTOBUF_SUBMODULE_VERSION="09745575a923640154bcf307fba8aedff47f240a" diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index b15b8d3b077..487479ba3da 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -38,7 +38,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) - 582743bf40c5d3639a70f98f183914a2c0cd0680 third_party/protobuf (v3.7.0-rc.2-20-g582743bf) + 09745575a923640154bcf307fba8aedff47f240a third_party/protobuf (v3.7.0-rc.2-247-g09745575) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) fa88c6017ddb490aa78c57bea682193f533ed69a third_party/upb (heads/master) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) From 724565372f3b1301f98776bfdc2460b58b50fcbc Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 29 May 2019 16:42:06 -0700 Subject: [PATCH 179/676] Fix the ref count issue --- src/core/lib/surface/completion_queue.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 9b30b3998a5..e883d472278 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -820,7 +820,6 @@ static void cq_end_op_for_pluck( static void functor_callback(void* arg, grpc_error* error) { auto* functor = static_cast(arg); functor->functor_run(functor, error == GRPC_ERROR_NONE); - GRPC_ERROR_UNREF(error); } /* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ From fc002a4d02656a7f21c29dbb6ac22a93181e7c75 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 29 May 2019 16:59:10 -0700 Subject: [PATCH 180/676] Remove ref for GRPC_ERROR_NONE --- src/core/lib/surface/completion_queue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index e883d472278..60a7d78b525 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -1356,7 +1356,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GRPC_CLOSURE_CREATE( functor_callback, callback, grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_REF(GRPC_ERROR_NONE)); + GRPC_ERROR_NONE); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 79f7abb45eab9f6f49ba694d4f8ce70f8e142b1d Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Wed, 29 May 2019 17:07:00 -0700 Subject: [PATCH 181/676] Update zlib dependency --- BUILD | 2 +- bazel/grpc_deps.bzl | 8 ++++---- third_party/zlib.BUILD | 2 +- tools/run_tests/sanity/check_bazel_workspace.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BUILD b/BUILD index 52c469f0b4a..b944d96c64b 100644 --- a/BUILD +++ b/BUILD @@ -1030,7 +1030,7 @@ grpc_cc_library( "src/core/lib/uri/uri_parser.h", ], external_deps = [ - "zlib", + "madler_zlib", ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 08022942be0..ac1ed5cbbef 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -32,8 +32,8 @@ def grpc_deps(): ) native.bind( - name = "zlib", - actual = "@com_github_madler_zlib//:z", + name = "madler_zlib", + actual = "@zlib//:zlib", ) native.bind( @@ -115,9 +115,9 @@ def grpc_deps(): url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz", ) - if "com_github_madler_zlib" not in native.existing_rules(): + if "zlib" not in native.existing_rules(): http_archive( - name = "com_github_madler_zlib", + name = "zlib", build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD", sha256 = "6d4d6640ca3121620995ee255945161821218752b551a1a180f4215f7d124d45", strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", diff --git a/third_party/zlib.BUILD b/third_party/zlib.BUILD index a71c85fa98d..95ae7c5a89c 100644 --- a/third_party/zlib.BUILD +++ b/third_party/zlib.BUILD @@ -1,5 +1,5 @@ cc_library( - name = "z", + name = "zlib", srcs = [ "adler32.c", "compress.c", diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index 2017f58323c..65aa72183d0 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -45,7 +45,7 @@ _TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly' _GRPC_DEP_NAMES = [ 'upb', 'boringssl', - 'com_github_madler_zlib', + 'zlib', 'com_google_protobuf', 'com_github_google_googletest', 'com_github_gflags_gflags', From facf4b30118a513ed264e21ca3b51eed954ba707 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 29 May 2019 22:02:11 -0700 Subject: [PATCH 182/676] PHP: Fix ZTS build error --- src/php/ext/grpc/php_grpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 1098075690a..74f536ea07b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -203,7 +203,7 @@ void register_fork_handlers() { } } -void apply_ini_settings() { +void apply_ini_settings(TSRMLS_D) { if (GRPC_G(enable_fork_support)) { char *enable_str = malloc(sizeof("GRPC_ENABLE_FORK_SUPPORT=1")); strcpy(enable_str, "GRPC_ENABLE_FORK_SUPPORT=1"); @@ -392,7 +392,7 @@ PHP_MINFO_FUNCTION(grpc) { */ PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { - apply_ini_settings(); + apply_ini_settings(TSRMLS_C); grpc_init(); register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); From 1259579a945ee442225bb79cbcf0ef01fd470d52 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 30 May 2019 08:25:17 -0700 Subject: [PATCH 183/676] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index ba91640269e..52ba1356929 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -649,7 +649,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; - (void)dealloc { [GRPCConnectivityMonitor unregisterObserver:self]; - + __block GRPCWrappedCall *wrappedCall = _wrappedCall; dispatch_async(_callQueue, ^{ wrappedCall = nil; From eb62ad3fae8a213c3d60ba24312c71323c1de7bf Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 30 May 2019 10:22:39 -0700 Subject: [PATCH 184/676] address comments --- src/objective-c/GRPCClient/GRPCInterceptor.h | 2 +- src/objective-c/GRPCClient/GRPCInterceptor.m | 50 ++++++++++++-------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.h b/src/objective-c/GRPCClient/GRPCInterceptor.h index 4b7bcdbff40..3b62c1b3ec0 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.h +++ b/src/objective-c/GRPCClient/GRPCInterceptor.h @@ -74,7 +74,7 @@ * receiveNextMessages * didReceiveInitialMetadata * didReceiveData - * didWriteData + * didWriteData receiveNextmessages * writeData ----- ----- ---- didReceiveInitialMetadata * receiveNextMessages | | | | | | didReceiveData * | V | V | V didWriteData diff --git a/src/objective-c/GRPCClient/GRPCInterceptor.m b/src/objective-c/GRPCClient/GRPCInterceptor.m index bf043fcd1f5..a385ecd7813 100644 --- a/src/objective-c/GRPCClient/GRPCInterceptor.m +++ b/src/objective-c/GRPCClient/GRPCInterceptor.m @@ -44,39 +44,49 @@ - (void)startNextInterceptorWithRequest:(GRPCRequestOptions *)requestOptions callOptions:(GRPCCallOptions *)callOptions { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; - }); + if (_nextInterceptor != nil) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor startWithRequestOptions:requestOptions callOptions:callOptions]; + }); + } } - (void)writeNextInterceptorWithData:(id)data { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor writeData:data]; - }); + if (_nextInterceptor != nil) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor writeData:data]; + }); + } } - (void)finishNextInterceptor { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor finish]; - }); + if (_nextInterceptor != nil) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor finish]; + }); + } } - (void)cancelNextInterceptor { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor cancel]; - }); + if (_nextInterceptor != nil) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor cancel]; + }); + } } /** Notify the next interceptor in the chain to receive more messages */ - (void)receiveNextInterceptorMessages:(NSUInteger)numberOfMessages { - id copiedNextInterceptor = _nextInterceptor; - dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ - [copiedNextInterceptor receiveNextMessages:numberOfMessages]; - }); + if (_nextInterceptor != nil) { + id copiedNextInterceptor = _nextInterceptor; + dispatch_async(copiedNextInterceptor.requestDispatchQueue, ^{ + [copiedNextInterceptor receiveNextMessages:numberOfMessages]; + }); + } } // Methods to forward GRPCResponseHandler callbacks to the previous object From cf0559197193581607030297edbc96e376f32131 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 30 May 2019 14:50:28 -0700 Subject: [PATCH 185/676] Add comment about LoggingInterceptor --- test/cpp/end2end/client_interceptors_end2end_test.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index d548a023bd1..583513edaa4 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -499,6 +499,10 @@ class BidiStreamingRpcHijackingInterceptorFactory } }; +// The logging interceptor is for testing purposes only. It is used to verify +// that all the appropriate hook points are invoked for an RPC. The counts are +// reset each time a new object of LoggingInterceptor is created, so only a +// single RPC should be made on the channel before calling the Verify methods. class LoggingInterceptor : public experimental::Interceptor { public: LoggingInterceptor(experimental::ClientRpcInfo* info) { From a874fd8bbbcb3bbc729cc98857e5417a9b523ed1 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 30 May 2019 15:20:10 -0700 Subject: [PATCH 186/676] Resolve review comments --- src/core/lib/security/transport/client_auth_filter.cc | 7 +++---- src/cpp/client/secure_credentials.cc | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index dbe288237d4..1062fc2f4fa 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -121,11 +121,10 @@ void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from, ->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context_copy") .release(); } - to->service_url = - (from->service_url == nullptr) ? nullptr : strdup(from->service_url); - to->method_name = - (from->method_name == nullptr) ? nullptr : strdup(from->method_name); + to->service_url = gpr_strdup(from->service_url); + to->method_name = gpr_strdup(from->method_name); } + void grpc_auth_metadata_context_reset( grpc_auth_metadata_context* auth_md_context) { if (auth_md_context->service_url != nullptr) { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 3d2a123180b..197112d4bb7 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -259,6 +259,8 @@ int MetadataCredentialsPluginWrapper::GetMetadata( return true; } if (w->plugin_->IsBlocking()) { + // The internals of context may be destroyed if GetMetadata is cancelled. + // Make a copy for InvokePlugin. grpc_auth_metadata_context context_copy = grpc_auth_metadata_context(); grpc_auth_metadata_context_copy(&context, &context_copy); // Asynchronous return. From f671b3d1366df06619a7d31e4b45b73d0898ef84 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 30 May 2019 15:39:37 -0700 Subject: [PATCH 187/676] Add hijacking interception hook points as valid for the GetRecv* functions --- include/grpcpp/impl/codegen/interceptor.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index b0f57f71196..18c7cf33e2f 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -174,20 +174,22 @@ class InterceptorBatchMethods { /// Returns a pointer to the modifiable received message. Note that the /// message is already deserialized but the type is not set; the interceptor /// should static_cast to the appropriate type before using it. This is valid - /// for POST_RECV_MESSAGE interceptions; nullptr for not valid + /// for PRE_RECV_MESSAGE and POST_RECV_MESSAGE interceptions; nullptr for not + /// valid virtual void* GetRecvMessage() = 0; /// Returns a modifiable multimap of the received initial metadata. - /// Valid for POST_RECV_INITIAL_METADATA interceptions; nullptr if not valid + /// Valid for PRE_RECV_INITIAL_METADATA and POST_RECV_INITIAL_METADATA + /// interceptions; nullptr if not valid virtual std::multimap* GetRecvInitialMetadata() = 0; - /// Returns a modifiable view of the received status on POST_RECV_STATUS - /// interceptions; nullptr if not valid. + /// Returns a modifiable view of the received status on PRE_RECV_STATUS and + /// POST_RECV_STATUS interceptions; nullptr if not valid. virtual Status* GetRecvStatus() = 0; /// Returns a modifiable multimap of the received trailing metadata on - /// POST_RECV_STATUS interceptions; nullptr if not valid + /// PRE_RECV_STATUS and POST_RECV_STATUS interceptions; nullptr if not valid virtual std::multimap* GetRecvTrailingMetadata() = 0; From a887f35a9ba5faff7416290e4bde37a062683386 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 30 May 2019 16:00:50 -0700 Subject: [PATCH 188/676] add a new struct - grpc_ssl_verify_peer_options and an API - grpc_ssl_credentials_create_ex. --- grpc.def | 1 + include/grpc/grpc_security.h | 59 ++++++++++++++++++- .../credentials/ssl/ssl_credentials.cc | 22 ++++++- .../credentials/ssl/ssl_credentials.h | 4 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + .../core/surface/public_headers_must_be_c89.c | 1 + 7 files changed, 86 insertions(+), 6 deletions(-) diff --git a/grpc.def b/grpc.def index 922f95383a3..32289dffeb7 100644 --- a/grpc.def +++ b/grpc.def @@ -101,6 +101,7 @@ EXPORTS grpc_google_default_credentials_create grpc_set_ssl_roots_override_callback grpc_ssl_credentials_create + grpc_ssl_credentials_create_ex grpc_call_credentials_release grpc_composite_channel_credentials_create grpc_composite_call_credentials_create diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index ebdf86b7d50..12a94dc95ea 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -163,6 +163,28 @@ typedef struct { const char* cert_chain; } grpc_ssl_pem_key_cert_pair; +/** Deprecated in favor of grpc_ssl_verify_peer_options. It will be removed + after all of its call sites are migrated to grpc_ssl_verify_peer_options. + Object that holds additional peer-verification options on a secure + channel. */ +typedef struct { + /** If non-NULL this callback will be invoked with the expected + target_name, the peer's certificate (in PEM format), and whatever + userdata pointer is set below. If a non-zero value is returned by this + callback then it is treated as a verification failure. Invocation of + the callback is blocking, so any implementation should be light-weight. + */ + int (*verify_peer_callback)(const char* target_name, const char* peer_pem, + void* userdata); + /** Arbitrary userdata that will be passed as the last argument to + verify_peer_callback. */ + void* verify_peer_callback_userdata; + /** A destruct callback that will be invoked when the channel is being + cleaned up. The userdata argument will be passed to it. The intent is + to perform any cleanup associated with that userdata. */ + void (*verify_peer_destruct)(void* userdata); +} verify_peer_options; + /** Object that holds additional peer-verification options on a secure channel. */ typedef struct { @@ -181,9 +203,11 @@ typedef struct { cleaned up. The userdata argument will be passed to it. The intent is to perform any cleanup associated with that userdata. */ void (*verify_peer_destruct)(void* userdata); -} verify_peer_options; +} grpc_ssl_verify_peer_options; -/** Creates an SSL credentials object. +/** Deprecated in favor of grpc_ssl_server_credentials_create_ex. It will be + removed after all of its call sites are migrated to + grpc_ssl_server_credentials_create_ex. Creates an SSL credentials object. - pem_root_certs is the NULL-terminated string containing the PEM encoding of the server root certificates. If this parameter is NULL, the implementation will first try to dereference the file pointed by the @@ -214,6 +238,37 @@ GRPCAPI grpc_channel_credentials* grpc_ssl_credentials_create( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved); +/* Creates an SSL credentials object. + - pem_root_certs is the NULL-terminated string containing the PEM encoding + of the server root certificates. If this parameter is NULL, the + implementation will first try to dereference the file pointed by the + GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable, and if that fails, + try to get the roots set by grpc_override_ssl_default_roots. Eventually, + if all these fail, it will try to get the roots from a well-known place on + disk (in the grpc install directory). + + gRPC has implemented root cache if the underlying OpenSSL library supports + it. The gRPC root certificates cache is only applicable on the default + root certificates, which is used when this parameter is nullptr. If user + provides their own pem_root_certs, when creating an SSL credential object, + gRPC would not be able to cache it, and each subchannel will generate a + copy of the root store. So it is recommended to avoid providing large room + pem with pem_root_certs parameter to avoid excessive memory consumption, + particularly on mobile platforms such as iOS. + - pem_key_cert_pair is a pointer on the object containing client's private + key and certificate chain. This parameter can be NULL if the client does + not have such a key/cert pair. + - verify_options is an optional verify_peer_options object which holds + additional options controlling how peer certificates are verified. For + example, you can supply a callback which receives the peer's certificate + with which you can do additional verification. Can be NULL, in which + case verification will retain default behavior. Any settings in + verify_options are copied during this call, so the verify_options + object can be released afterwards. */ +GRPCAPI grpc_channel_credentials* grpc_ssl_credentials_create_ex( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const grpc_ssl_verify_peer_options* verify_options, void* reserved); + /** --- grpc_call_credentials object. A call credentials object represents a way to authenticate on a particular diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc index 83db86f1eac..65e57cebeb5 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc @@ -46,7 +46,7 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp, grpc_ssl_credentials::grpc_ssl_credentials( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options) + const grpc_ssl_verify_peer_options* verify_options) : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) { build_config(pem_root_certs, pem_key_cert_pair, verify_options); } @@ -94,7 +94,7 @@ grpc_ssl_credentials::create_security_connector( void grpc_ssl_credentials::build_config( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options) { + const grpc_ssl_verify_peer_options* verify_options) { config_.pem_root_certs = gpr_strdup(pem_root_certs); if (pem_key_cert_pair != nullptr) { GPR_ASSERT(pem_key_cert_pair->private_key != nullptr); @@ -117,6 +117,8 @@ void grpc_ssl_credentials::build_config( } } +/* Deprecated in favor of grpc_ssl_credentials_create_ex. Will be removed + * once all of its call sites are migrated to grpc_ssl_credentials_create_ex. */ grpc_channel_credentials* grpc_ssl_credentials_create( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved) { @@ -128,6 +130,22 @@ grpc_channel_credentials* grpc_ssl_credentials_create( 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); GPR_ASSERT(reserved == nullptr); + return grpc_core::New( + pem_root_certs, pem_key_cert_pair, + reinterpret_cast(verify_options)); +} + +grpc_channel_credentials* grpc_ssl_credentials_create_ex( + const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, + const grpc_ssl_verify_peer_options* verify_options, void* reserved) { + GRPC_API_TRACE( + "grpc_ssl_credentials_create(pem_root_certs=%s, " + "pem_key_cert_pair=%p, " + "verify_options=%p, " + "reserved=%p)", + 4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved)); + GPR_ASSERT(reserved == nullptr); + return grpc_core::New(pem_root_certs, pem_key_cert_pair, verify_options); } diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index e1174327b30..545a27f0be4 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -28,7 +28,7 @@ class grpc_ssl_credentials : public grpc_channel_credentials { public: grpc_ssl_credentials(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options); + const grpc_ssl_verify_peer_options* verify_options); ~grpc_ssl_credentials() override; @@ -41,7 +41,7 @@ class grpc_ssl_credentials : public grpc_channel_credentials { private: void build_config(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, - const verify_peer_options* verify_options); + const grpc_ssl_verify_peer_options* verify_options); grpc_ssl_config config_; }; diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index f8a31286115..b1165a6d6eb 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -124,6 +124,7 @@ grpc_channel_credentials_release_type grpc_channel_credentials_release_import; grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import; grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import; grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import; +grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import; grpc_call_credentials_release_type grpc_call_credentials_release_import; grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import; grpc_composite_call_credentials_create_type grpc_composite_call_credentials_create_import; @@ -393,6 +394,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create"); grpc_set_ssl_roots_override_callback_import = (grpc_set_ssl_roots_override_callback_type) GetProcAddress(library, "grpc_set_ssl_roots_override_callback"); grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create"); + grpc_ssl_credentials_create_ex_import = (grpc_ssl_credentials_create_ex_type) GetProcAddress(library, "grpc_ssl_credentials_create_ex"); grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release"); grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create"); grpc_composite_call_credentials_create_import = (grpc_composite_call_credentials_create_type) GetProcAddress(library, "grpc_composite_call_credentials_create"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index c25d789a95b..5809194f1ae 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -347,6 +347,9 @@ extern grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_cal typedef grpc_channel_credentials*(*grpc_ssl_credentials_create_type)(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const verify_peer_options* verify_options, void* reserved); extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import; #define grpc_ssl_credentials_create grpc_ssl_credentials_create_import +typedef grpc_channel_credentials*(*grpc_ssl_credentials_create_ex_type)(const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair, const grpc_ssl_verify_peer_options* verify_options, void* reserved); +extern grpc_ssl_credentials_create_ex_type grpc_ssl_credentials_create_ex_import; +#define grpc_ssl_credentials_create_ex grpc_ssl_credentials_create_ex_import typedef void(*grpc_call_credentials_release_type)(grpc_call_credentials* creds); extern grpc_call_credentials_release_type grpc_call_credentials_release_import; #define grpc_call_credentials_release grpc_call_credentials_release_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index fa02e76ec92..3aaa1e709ee 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -161,6 +161,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_google_default_credentials_create); printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback); printf("%lx", (unsigned long) grpc_ssl_credentials_create); + printf("%lx", (unsigned long) grpc_ssl_credentials_create_ex); printf("%lx", (unsigned long) grpc_call_credentials_release); printf("%lx", (unsigned long) grpc_composite_channel_credentials_create); printf("%lx", (unsigned long) grpc_composite_call_credentials_create); From b6e5827315e0b28c54c23c7ab9755814defb184e Mon Sep 17 00:00:00 2001 From: "1524995078@qq.com" <51152648+OceanOfWest@users.noreply.github.com> Date: Fri, 31 May 2019 10:31:37 +0800 Subject: [PATCH 189/676] remove python version number to release binding to exact version --- tools/run_tests/start_port_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py index 5b776f3b305..cca9859d1e9 100755 --- a/tools/run_tests/start_port_server.py +++ b/tools/run_tests/start_port_server.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python # Copyright 2017 gRPC authors. # From e3f976f4d5885d6645e0b5fa57f2eeb9af74652d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 31 May 2019 07:27:18 -0700 Subject: [PATCH 190/676] Resolve merge issue --- .../tests/InteropTests/InteropTests.m | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 70e75bf6990..7d4aee0bc90 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -80,81 +80,6 @@ BOOL isRemoteInteropTest(NSString *host) { return [host isEqualToString:@"grpc-test.sandbox.googleapis.com"]; } -// Convenience class to use blocks as callbacks -@interface InteropTestsBlockCallbacks : NSObject - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback - writeMessageCallback:(void (^)(void))writeMessageCallback; - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback; - -@end - -@implementation InteropTestsBlockCallbacks { - void (^_initialMetadataCallback)(NSDictionary *); - void (^_messageCallback)(id); - void (^_closeCallback)(NSDictionary *, NSError *); - void (^_writeMessageCallback)(void); - dispatch_queue_t _dispatchQueue; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback - writeMessageCallback:(void (^)(void))writeMessageCallback { - if ((self = [super init])) { - _initialMetadataCallback = initialMetadataCallback; - _messageCallback = messageCallback; - _closeCallback = closeCallback; - _writeMessageCallback = writeMessageCallback; - _dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL); - } - return self; -} - -- (instancetype)initWithInitialMetadataCallback:(void (^)(NSDictionary *))initialMetadataCallback - messageCallback:(void (^)(id))messageCallback - closeCallback:(void (^)(NSDictionary *, NSError *))closeCallback { - return [self initWithInitialMetadataCallback:initialMetadataCallback - messageCallback:messageCallback - closeCallback:closeCallback - writeMessageCallback:nil]; -} - -- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { - if (_initialMetadataCallback) { - _initialMetadataCallback(initialMetadata); - } -} - -- (void)didReceiveProtoMessage:(GPBMessage *)message { - if (_messageCallback) { - _messageCallback(message); - } -} - -- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error { - if (_closeCallback) { - _closeCallback(trailingMetadata, error); - } -} - -- (void)didWriteMessage { - if (_writeMessageCallback) { - _writeMessageCallback(); - } -} - -- (dispatch_queue_t)dispatchQueue { - return _dispatchQueue; -} - -@end - @interface DefaultInterceptorFactory : NSObject - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager; From 4a4cf280a1d5f8690ee063a22a6b4b1d1d49f27f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 31 May 2019 10:37:58 -0400 Subject: [PATCH 191/676] also generate code with "lite_client" option set --- .../math_with_protoc_options.proto | 65 +++++++++++++++++++ src/csharp/generate_proto_csharp.sh | 2 + 2 files changed, 67 insertions(+) create mode 100644 src/csharp/Grpc.Examples/math_with_protoc_options.proto diff --git a/src/csharp/Grpc.Examples/math_with_protoc_options.proto b/src/csharp/Grpc.Examples/math_with_protoc_options.proto new file mode 100644 index 00000000000..ca13c6d4466 --- /dev/null +++ b/src/csharp/Grpc.Examples/math_with_protoc_options.proto @@ -0,0 +1,65 @@ + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package math_with_protoc_options; + +message DivArgs { + int64 dividend = 1; + int64 divisor = 2; +} + +message DivReply { + int64 quotient = 1; + int64 remainder = 2; +} + +message FibArgs { + int64 limit = 1; +} + +message Num { + int64 num = 1; +} + +message FibReply { + int64 count = 1; +} + +service Math { + // Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient + // and remainder. + rpc Div (DivArgs) returns (DivReply) { + } + + // DivMany accepts an arbitrary number of division args from the client stream + // and sends back the results in the reply stream. The stream continues until + // the client closes its end; the server does the same after sending all the + // replies. The stream ends immediately if either end aborts. + rpc DivMany (stream DivArgs) returns (stream DivReply) { + } + + // Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib + // generates up to limit numbers; otherwise it continues until the call is + // canceled. Unlike Fib above, Fib has no final FibReply. + rpc Fib (FibArgs) returns (stream Num) { + } + + // Sum sums a stream of numbers, returning the final result once the stream + // is closed. + rpc Sum (stream Num) returns (Num) { + } +} diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh index e79728ff959..81463ace6ad 100755 --- a/src/csharp/generate_proto_csharp.sh +++ b/src/csharp/generate_proto_csharp.sh @@ -26,6 +26,8 @@ TESTING_DIR=src/csharp/Grpc.IntegrationTesting $PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \ -I src/proto src/proto/math/math.proto +$PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR --grpc_opt=lite_client,no_server \ + -I src/csharp/Grpc.Examples src/csharp/Grpc.Examples/math_with_protoc_options.proto $PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \ -I src/proto src/proto/grpc/health/v1/health.proto From 8c27e86b8b0eaa163ed1186f10e33346d06bf040 Mon Sep 17 00:00:00 2001 From: "yuangongji (A)" <82787816@qq.com> Date: Fri, 31 May 2019 22:40:55 +0800 Subject: [PATCH 192/676] some typo errors --- include/grpc/grpc_security_constants.h | 2 +- include/grpc/impl/codegen/gpr_types.h | 2 +- include/grpc/slice.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index a082f670107..1be524a78f8 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -96,7 +96,7 @@ typedef enum { /** Server requests client certificate and enforces that the client presents a certificate. - The cerificate presented by the client is verified by the gRPC framework. + The certificate presented by the client is verified by the gRPC framework. (For a successful connection the client needs to present a certificate that can be verified against the root certificate configured by the server) diff --git a/include/grpc/impl/codegen/gpr_types.h b/include/grpc/impl/codegen/gpr_types.h index d7bb54527ec..6daf3398619 100644 --- a/include/grpc/impl/codegen/gpr_types.h +++ b/include/grpc/impl/codegen/gpr_types.h @@ -48,7 +48,7 @@ typedef struct gpr_timespec { int64_t tv_sec; int32_t tv_nsec; /** Against which clock was this time measured? (or GPR_TIMESPAN if - this is a relative time meaure) */ + this is a relative time measure) */ gpr_clock_type clock_type; } gpr_timespec; diff --git a/include/grpc/slice.h b/include/grpc/slice.h index 192a8cfeef4..51fc62b44df 100644 --- a/include/grpc/slice.h +++ b/include/grpc/slice.h @@ -107,7 +107,7 @@ GPRAPI grpc_slice grpc_slice_sub_no_ref(grpc_slice s, size_t begin, size_t end); /** Splits s into two: modifies s to be s[0:split], and returns a new slice, sharing a refcount with s, that contains s[split:s.length]. - Requires s intialized, split <= s.length */ + Requires s initialized, split <= s.length */ GPRAPI grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split); typedef enum { @@ -124,7 +124,7 @@ GPRAPI grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* s, size_t split, /** Splits s into two: modifies s to be s[split:s.length], and returns a new slice, sharing a refcount with s, that contains s[0:split]. - Requires s intialized, split <= s.length */ + Requires s initialized, split <= s.length */ GPRAPI grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split); GPRAPI grpc_slice grpc_empty_slice(void); From 8cb8d5818574024ff18359be48c17729423e1fec Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 31 May 2019 10:53:06 -0400 Subject: [PATCH 193/676] add generated code for math_with_protoc_options.proto --- .../Grpc.Examples/MathWithProtocOptions.cs | 759 ++++++++++++++++++ .../MathWithProtocOptionsGrpc.cs | 208 +++++ 2 files changed, 967 insertions(+) create mode 100644 src/csharp/Grpc.Examples/MathWithProtocOptions.cs create mode 100644 src/csharp/Grpc.Examples/MathWithProtocOptionsGrpc.cs diff --git a/src/csharp/Grpc.Examples/MathWithProtocOptions.cs b/src/csharp/Grpc.Examples/MathWithProtocOptions.cs new file mode 100644 index 00000000000..ef9a5a4ff5c --- /dev/null +++ b/src/csharp/Grpc.Examples/MathWithProtocOptions.cs @@ -0,0 +1,759 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: math_with_protoc_options.proto +// +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace MathWithProtocOptions { + + /// Holder for reflection information generated from math_with_protoc_options.proto + public static partial class MathWithProtocOptionsReflection { + + #region Descriptor + /// File descriptor for math_with_protoc_options.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static MathWithProtocOptionsReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "Ch5tYXRoX3dpdGhfcHJvdG9jX29wdGlvbnMucHJvdG8SGG1hdGhfd2l0aF9w", + "cm90b2Nfb3B0aW9ucyIsCgdEaXZBcmdzEhAKCGRpdmlkZW5kGAEgASgDEg8K", + "B2Rpdmlzb3IYAiABKAMiLwoIRGl2UmVwbHkSEAoIcXVvdGllbnQYASABKAMS", + "EQoJcmVtYWluZGVyGAIgASgDIhgKB0ZpYkFyZ3MSDQoFbGltaXQYASABKAMi", + "EgoDTnVtEgsKA251bRgBIAEoAyIZCghGaWJSZXBseRINCgVjb3VudBgBIAEo", + "AzLEAgoETWF0aBJOCgNEaXYSIS5tYXRoX3dpdGhfcHJvdG9jX29wdGlvbnMu", + "RGl2QXJncxoiLm1hdGhfd2l0aF9wcm90b2Nfb3B0aW9ucy5EaXZSZXBseSIA", + "ElYKB0Rpdk1hbnkSIS5tYXRoX3dpdGhfcHJvdG9jX29wdGlvbnMuRGl2QXJn", + "cxoiLm1hdGhfd2l0aF9wcm90b2Nfb3B0aW9ucy5EaXZSZXBseSIAKAEwARJL", + "CgNGaWISIS5tYXRoX3dpdGhfcHJvdG9jX29wdGlvbnMuRmliQXJncxodLm1h", + "dGhfd2l0aF9wcm90b2Nfb3B0aW9ucy5OdW0iADABEkcKA1N1bRIdLm1hdGhf", + "d2l0aF9wcm90b2Nfb3B0aW9ucy5OdW0aHS5tYXRoX3dpdGhfcHJvdG9jX29w", + "dGlvbnMuTnVtIgAoAWIGcHJvdG8z")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::MathWithProtocOptions.DivArgs), global::MathWithProtocOptions.DivArgs.Parser, new[]{ "Dividend", "Divisor" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MathWithProtocOptions.DivReply), global::MathWithProtocOptions.DivReply.Parser, new[]{ "Quotient", "Remainder" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MathWithProtocOptions.FibArgs), global::MathWithProtocOptions.FibArgs.Parser, new[]{ "Limit" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MathWithProtocOptions.Num), global::MathWithProtocOptions.Num.Parser, new[]{ "Num_" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::MathWithProtocOptions.FibReply), global::MathWithProtocOptions.FibReply.Parser, new[]{ "Count" }, null, null, null) + })); + } + #endregion + + } + #region Messages + public sealed partial class DivArgs : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DivArgs()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.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_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DivArgs Clone() { + return new DivArgs(this); + } + + /// 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 { + dividend_ = value; + } + } + + /// 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 { + divisor_ = value; + } + } + + [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; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Dividend != other.Dividend) return false; + if (Divisor != other.Divisor) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Dividend != 0L) hash ^= Dividend.GetHashCode(); + if (Divisor != 0L) hash ^= Divisor.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.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 (Dividend != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Dividend); + } + if (Divisor != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Divisor); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Dividend != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Dividend); + } + if (Divisor != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Divisor); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DivArgs other) { + if (other == null) { + return; + } + if (other.Dividend != 0L) { + Dividend = other.Dividend; + } + if (other.Divisor != 0L) { + Divisor = other.Divisor; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Dividend = input.ReadInt64(); + break; + } + case 16: { + Divisor = input.ReadInt64(); + break; + } + } + } + } + + } + + public sealed partial class DivReply : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DivReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.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_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public DivReply Clone() { + return new DivReply(this); + } + + /// 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 { + quotient_ = value; + } + } + + /// 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 { + remainder_ = value; + } + } + + [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; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Quotient != other.Quotient) return false; + if (Remainder != other.Remainder) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Quotient != 0L) hash ^= Quotient.GetHashCode(); + if (Remainder != 0L) hash ^= Remainder.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.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 (Quotient != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Quotient); + } + if (Remainder != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Remainder); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Quotient != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Quotient); + } + if (Remainder != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Remainder); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(DivReply other) { + if (other == null) { + return; + } + if (other.Quotient != 0L) { + Quotient = other.Quotient; + } + if (other.Remainder != 0L) { + Remainder = other.Remainder; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Quotient = input.ReadInt64(); + break; + } + case 16: { + Remainder = input.ReadInt64(); + break; + } + } + } + } + + } + + public sealed partial class FibArgs : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FibArgs()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.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_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public FibArgs Clone() { + return new FibArgs(this); + } + + /// 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 { + limit_ = value; + } + } + + [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; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Limit != other.Limit) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Limit != 0L) hash ^= Limit.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.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); + output.WriteInt64(Limit); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Limit != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Limit); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(FibArgs other) { + if (other == null) { + return; + } + if (other.Limit != 0L) { + Limit = other.Limit; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Limit = input.ReadInt64(); + break; + } + } + } + } + + } + + public sealed partial class Num : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Num()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.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_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public Num Clone() { + return new Num(this); + } + + /// 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 { + num_ = value; + } + } + + [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; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Num_ != other.Num_) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Num_ != 0L) hash ^= Num_.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.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); + output.WriteInt64(Num_); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Num_ != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Num_); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(Num other) { + if (other == null) { + return; + } + if (other.Num_ != 0L) { + Num_ = other.Num_; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Num_ = input.ReadInt64(); + break; + } + } + } + } + + } + + public sealed partial class FibReply : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FibReply()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.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_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public FibReply Clone() { + return new FibReply(this); + } + + /// 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 { + count_ = value; + } + } + + [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; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Count != other.Count) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Count != 0L) hash ^= Count.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.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); + output.WriteInt64(Count); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Count != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(FibReply other) { + if (other == null) { + return; + } + if (other.Count != 0L) { + Count = other.Count; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Count = input.ReadInt64(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/src/csharp/Grpc.Examples/MathWithProtocOptionsGrpc.cs b/src/csharp/Grpc.Examples/MathWithProtocOptionsGrpc.cs new file mode 100644 index 00000000000..dd61b72163f --- /dev/null +++ b/src/csharp/Grpc.Examples/MathWithProtocOptionsGrpc.cs @@ -0,0 +1,208 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: math_with_protoc_options.proto +// +// Original file comments: +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma warning disable 0414, 1591 +#region Designer generated code + +using grpc = global::Grpc.Core; + +namespace MathWithProtocOptions { + public static partial class Math + { + static readonly string __ServiceName = "math_with_protoc_options.Math"; + + static readonly grpc::Marshaller __Marshaller_math_with_protoc_options_DivArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::MathWithProtocOptions.DivArgs.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_math_with_protoc_options_DivReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::MathWithProtocOptions.DivReply.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_math_with_protoc_options_FibArgs = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::MathWithProtocOptions.FibArgs.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_math_with_protoc_options_Num = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::MathWithProtocOptions.Num.Parser.ParseFrom); + + static readonly grpc::Method __Method_Div = new grpc::Method( + grpc::MethodType.Unary, + __ServiceName, + "Div", + __Marshaller_math_with_protoc_options_DivArgs, + __Marshaller_math_with_protoc_options_DivReply); + + static readonly grpc::Method __Method_DivMany = new grpc::Method( + grpc::MethodType.DuplexStreaming, + __ServiceName, + "DivMany", + __Marshaller_math_with_protoc_options_DivArgs, + __Marshaller_math_with_protoc_options_DivReply); + + static readonly grpc::Method __Method_Fib = new grpc::Method( + grpc::MethodType.ServerStreaming, + __ServiceName, + "Fib", + __Marshaller_math_with_protoc_options_FibArgs, + __Marshaller_math_with_protoc_options_Num); + + static readonly grpc::Method __Method_Sum = new grpc::Method( + grpc::MethodType.ClientStreaming, + __ServiceName, + "Sum", + __Marshaller_math_with_protoc_options_Num, + __Marshaller_math_with_protoc_options_Num); + + /// Service descriptor + public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor + { + get { return global::MathWithProtocOptions.MathWithProtocOptionsReflection.Descriptor.Services[0]; } + } + + /// Lite client for Math + public partial class MathClient : grpc::LiteClientBase + { + /// Creates a new client for Math that uses a custom CallInvoker. + /// The callInvoker to use to make remote calls. + public MathClient(grpc::CallInvoker callInvoker) : base(callInvoker) + { + } + /// Protected parameterless constructor to allow creation of test doubles. + protected MathClient() : base() + { + } + + /// + /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient + /// and remainder. + /// + /// The request to send to the server. + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The response received from the server. + public virtual global::MathWithProtocOptions.DivReply Div(global::MathWithProtocOptions.DivArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return Div(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient + /// and remainder. + /// + /// The request to send to the server. + /// The options for the call. + /// The response received from the server. + public virtual global::MathWithProtocOptions.DivReply Div(global::MathWithProtocOptions.DivArgs request, grpc::CallOptions options) + { + return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request); + } + /// + /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient + /// and remainder. + /// + /// The request to send to the server. + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The call object. + public virtual grpc::AsyncUnaryCall DivAsync(global::MathWithProtocOptions.DivArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return DivAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient + /// and remainder. + /// + /// The request to send to the server. + /// The options for the call. + /// The call object. + public virtual grpc::AsyncUnaryCall DivAsync(global::MathWithProtocOptions.DivArgs request, grpc::CallOptions options) + { + return CallInvoker.AsyncUnaryCall(__Method_Div, null, options, request); + } + /// + /// DivMany accepts an arbitrary number of division args from the client stream + /// and sends back the results in the reply stream. The stream continues until + /// the client closes its end; the server does the same after sending all the + /// replies. The stream ends immediately if either end aborts. + /// + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The call object. + public virtual grpc::AsyncDuplexStreamingCall DivMany(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return DivMany(new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// DivMany accepts an arbitrary number of division args from the client stream + /// and sends back the results in the reply stream. The stream continues until + /// the client closes its end; the server does the same after sending all the + /// replies. The stream ends immediately if either end aborts. + /// + /// The options for the call. + /// The call object. + public virtual grpc::AsyncDuplexStreamingCall DivMany(grpc::CallOptions options) + { + return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options); + } + /// + /// Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib + /// generates up to limit numbers; otherwise it continues until the call is + /// canceled. Unlike Fib above, Fib has no final FibReply. + /// + /// The request to send to the server. + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The call object. + public virtual grpc::AsyncServerStreamingCall Fib(global::MathWithProtocOptions.FibArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return Fib(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib + /// generates up to limit numbers; otherwise it continues until the call is + /// canceled. Unlike Fib above, Fib has no final FibReply. + /// + /// The request to send to the server. + /// The options for the call. + /// The call object. + public virtual grpc::AsyncServerStreamingCall Fib(global::MathWithProtocOptions.FibArgs request, grpc::CallOptions options) + { + return CallInvoker.AsyncServerStreamingCall(__Method_Fib, null, options, request); + } + /// + /// Sum sums a stream of numbers, returning the final result once the stream + /// is closed. + /// + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The call object. + public virtual grpc::AsyncClientStreamingCall Sum(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) + { + return Sum(new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sum sums a stream of numbers, returning the final result once the stream + /// is closed. + /// + /// The options for the call. + /// The call object. + public virtual grpc::AsyncClientStreamingCall Sum(grpc::CallOptions options) + { + return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options); + } + } + + } +} +#endregion From a432e2f50276ba4997c2aecdf41f7f6f75c454ee Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 31 May 2019 10:53:40 -0400 Subject: [PATCH 194/676] check callInvoker is not null --- src/csharp/Grpc.Core.Api/LiteClientBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/LiteClientBase.cs b/src/csharp/Grpc.Core.Api/LiteClientBase.cs index a978cdf09e0..c3215f016a0 100644 --- a/src/csharp/Grpc.Core.Api/LiteClientBase.cs +++ b/src/csharp/Grpc.Core.Api/LiteClientBase.cs @@ -17,6 +17,7 @@ #endregion using System; +using Grpc.Core.Utils; namespace Grpc.Core { @@ -47,7 +48,7 @@ namespace Grpc.Core /// The CallInvoker for remote call invocation. public LiteClientBase(CallInvoker callInvoker) { - this.callInvoker = callInvoker; + this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker, nameof(callInvoker)); } /// From 381126fe2bd3bee25dc9b7aadc140f8782bfcf9d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 31 May 2019 14:03:51 -0700 Subject: [PATCH 195/676] Fix typo --- src/objective-c/GRPCClient/GRPCCall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 4a1d98b7ba5..d02ec601727 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -174,7 +174,7 @@ extern NSString *const kGRPCTrailersKey; * interceptor, implement didReceiveData: instead. To implement an interceptor, please leave this * method unimplemented and implement didReceiveData: method instead. If this method and * didReceiveRawMessage are implemented at the same time, implementation of this method will be - * ingored. + * ignored. * * Issued when a message is received from the server. The message is the raw data received from the * server, with decompression and without proto deserialization. From 434b3b62e585e122e07d34d55d71a6e5a4cba7ad Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Fri, 24 May 2019 10:24:17 -0700 Subject: [PATCH 196/676] Applied the best practice using global configuration --- src/core/ext/filters/client_channel/backup_poller.cc | 5 ++--- src/core/ext/filters/client_channel/backup_poller.h | 7 +++++-- .../ext/filters/client_channel/client_channel_plugin.cc | 2 ++ .../resolver/dns/c_ares/dns_resolver_ares.cc | 9 ++++++--- src/core/lib/gprpp/global_config.h | 9 +++++++++ src/core/lib/iomgr/iomgr.cc | 6 +++--- test/cpp/end2end/client_lb_end2end_test.cc | 9 ++++----- test/cpp/end2end/grpclb_end2end_test.cc | 9 ++++----- test/cpp/end2end/service_config_end2end_test.cc | 9 ++++----- test/cpp/end2end/xds_end2end_test.cc | 9 ++++----- 10 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index dd761694414..9e51a83415e 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -65,8 +65,8 @@ GPR_GLOBAL_CONFIG_DEFINE_INT32( "idleness), so that the next RPC on this channel won't fail. Set to 0 to " "turn off the backup polls."); -static void init_globals() { - gpr_mu_init(&g_poller_mu); +void grpc_client_channel_global_init_backup_polling() { + gpr_once_init(&g_once, [] { gpr_mu_init(&g_poller_mu); }); int32_t poll_interval_ms = GPR_GLOBAL_CONFIG_GET(grpc_client_channel_backup_poll_interval_ms); if (poll_interval_ms < 0) { @@ -153,7 +153,6 @@ static void g_poller_init_locked() { void grpc_client_channel_start_backup_polling( grpc_pollset_set* interested_parties) { - gpr_once_init(&g_once, init_globals); if (g_poll_interval_ms == 0) { return; } diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h index e1bf4f88b2a..b412081b960 100644 --- a/src/core/ext/filters/client_channel/backup_poller.h +++ b/src/core/ext/filters/client_channel/backup_poller.h @@ -27,11 +27,14 @@ GPR_GLOBAL_CONFIG_DECLARE_INT32(grpc_client_channel_backup_poll_interval_ms); -/* Start polling \a interested_parties periodically in the timer thread */ +/* Initializes backup polling. */ +void grpc_client_channel_global_init_backup_polling(); + +/* Starts polling \a interested_parties periodically in the timer thread. */ void grpc_client_channel_start_backup_polling( grpc_pollset_set* interested_parties); -/* Stop polling \a interested_parties */ +/* Stops polling \a interested_parties. */ void grpc_client_channel_stop_backup_polling( grpc_pollset_set* interested_parties); diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index e564df8be33..3a7492d82d9 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -24,6 +24,7 @@ #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h" @@ -62,6 +63,7 @@ void grpc_client_channel_init(void) { GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter, (void*)&grpc_client_channel_filter); grpc_http_connect_register_handshaker_factory(); + grpc_client_channel_global_init_backup_polling(); } void grpc_client_channel_shutdown(void) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 00358736a94..32a339af359 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -473,10 +473,13 @@ static bool should_use_ares(const char* resolver_env) { } #endif /* GRPC_UV */ +static bool g_use_ares_dns_resolver; + void grpc_resolver_dns_ares_init() { grpc_core::UniquePtr resolver = GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); if (should_use_ares(resolver.get())) { + g_use_ares_dns_resolver = true; gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); grpc_error* error = grpc_ares_init(); @@ -491,13 +494,13 @@ void grpc_resolver_dns_ares_init() { grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( grpc_core::UniquePtr( grpc_core::New())); + } else { + g_use_ares_dns_resolver = false; } } void grpc_resolver_dns_ares_shutdown() { - grpc_core::UniquePtr resolver = - GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver); - if (should_use_ares(resolver.get())) { + if (g_use_ares_dns_resolver) { address_sorting_shutdown(); grpc_ares_cleanup(); } diff --git a/src/core/lib/gprpp/global_config.h b/src/core/lib/gprpp/global_config.h index a1bbf07564c..ed986b8e04d 100644 --- a/src/core/lib/gprpp/global_config.h +++ b/src/core/lib/gprpp/global_config.h @@ -59,6 +59,15 @@ // // Declaring config variables for other modules to access: // GPR_GLOBAL_CONFIG_DECLARE_*TYPE*(name) +// +// * Caveat for setting global configs at runtime +// +// Setting global configs at runtime multiple times is safe but it doesn't +// mean that it will have a valid effect on the module depending configs. +// In unit tests, it may be unpredictable to set different global configs +// between test cases because grpc init and shutdown can ignore changes. +// It's considered safe to set global configs before the first call to +// grpc_init(). // -------------------------------------------------------------------- // How to customize the global configuration system: diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index b09d19fa759..802e3bdcb4d 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -49,6 +49,7 @@ static gpr_mu g_mu; static gpr_cv g_rcv; static int g_shutdown; static grpc_iomgr_object g_root_object; +static bool g_grpc_abort_on_leaks; void grpc_iomgr_init() { grpc_core::ExecCtx exec_ctx; @@ -62,6 +63,7 @@ void grpc_iomgr_init() { grpc_iomgr_platform_init(); grpc_timer_list_init(); grpc_core::grpc_errqueue_init(); + g_grpc_abort_on_leaks = GPR_GLOBAL_CONFIG_GET(grpc_abort_on_leaks); } void grpc_iomgr_start() { grpc_timer_manager_init(); } @@ -189,6 +191,4 @@ void grpc_iomgr_unregister_object(grpc_iomgr_object* obj) { gpr_free(obj->name); } -bool grpc_iomgr_abort_on_leaks(void) { - return GPR_GLOBAL_CONFIG_GET(grpc_abort_on_leaks); -} +bool grpc_iomgr_abort_on_leaks(void) { return g_grpc_abort_on_leaks; } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index b623348e13f..f6d4a48b6f0 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -139,11 +139,7 @@ class ClientLbEnd2endTest : public ::testing::Test { : server_host_("localhost"), kRequestMessage_("Live long and prosper."), creds_(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } + grpc_fake_transport_security_credentials_create())) {} void SetUp() override { grpc_init(); @@ -1485,6 +1481,9 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { } // namespace grpc int main(int argc, char** argv) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 50b1383e7e1..70c443412aa 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -372,11 +372,7 @@ class GrpclbEnd2endTest : public ::testing::Test { num_backends_(num_backends), num_balancers_(num_balancers), client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } + client_load_reporting_interval_seconds) {} void SetUp() override { response_generator_ = @@ -1994,6 +1990,9 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { } // namespace grpc int main(int argc, char** argv) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 14786b98f85..8bf4a7c22ff 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -117,11 +117,7 @@ class ServiceConfigEnd2endTest : public ::testing::Test { : server_host_("localhost"), kRequestMessage_("Live long and prosper."), creds_(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } + grpc_fake_transport_security_credentials_create())) {} void SetUp() override { grpc_init(); @@ -615,6 +611,9 @@ TEST_F(ServiceConfigEnd2endTest, } // namespace grpc int main(int argc, char** argv) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 87a231c588d..eac6f32a538 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -368,11 +368,7 @@ class XdsEnd2endTest : public ::testing::Test { num_backends_(num_backends), num_balancers_(num_balancers), client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } + client_load_reporting_interval_seconds) {} void SetUp() override { response_generator_ = @@ -1405,6 +1401,9 @@ class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { } // namespace grpc int main(int argc, char** argv) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); From 8fa95462a1101a837cefb549d3052fec7b7a01e5 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Fri, 31 May 2019 14:07:07 -0700 Subject: [PATCH 197/676] Put strncpy in parens to silence GCC warning GCC warns (-Wstringop-truncation) because the destination buffer size is identical to max-size, leading to a potential char[] with no null terminator. nanopb can handle it fine, and parantheses around strncpy silence that compiler warning. nanopb treatment of string buffers with specific max length seems dangerous in general, specifically when read from, but this particular case should be correct, as the buffer is only ever read by nanopb itself, which takes the max size into consideration, in addition to the null terminator. --- .../client_channel/lb_policy/grpclb/load_balancer_api.cc | 8 ++++++-- .../client_channel/lb_policy/xds/xds_load_balancer_api.cc | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc index b51db110395..22cefc937b0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -67,8 +67,12 @@ grpc_grpclb_request* grpc_grpclb_request_create(const char* lb_service_name) { req->has_client_stats = false; req->has_initial_request = true; req->initial_request.has_name = true; - strncpy(req->initial_request.name, lb_service_name, - GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH); + // GCC warns (-Wstringop-truncation) because the destination + // buffer size is identical to max-size, leading to a potential + // char[] with no null terminator. nanopb can handle it fine, + // and parantheses around strncpy silence that compiler warning. + (strncpy(req->initial_request.name, lb_service_name, + GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH)); return req; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc index 90094974a14..58f26bf54ec 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc @@ -67,8 +67,12 @@ xds_grpclb_request* xds_grpclb_request_create(const char* lb_service_name) { req->has_client_stats = false; req->has_initial_request = true; req->initial_request.has_name = true; - strncpy(req->initial_request.name, lb_service_name, - XDS_SERVICE_NAME_MAX_LENGTH); + // GCC warns (-Wstringop-truncation) because the destination + // buffer size is identical to max-size, leading to a potential + // char[] with no null terminator. nanopb can handle it fine, + // and parantheses around strncpy silence that compiler warning. + (strncpy(req->initial_request.name, lb_service_name, + XDS_SERVICE_NAME_MAX_LENGTH)); return req; } From 371a55a0fff1480818932c44feaf76fe00e124dc Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 31 May 2019 10:36:00 -0700 Subject: [PATCH 198/676] Update Python packages before building ARM wheels. --- tools/dockerfile/grpc_artifact_linux_armv6/Dockerfile | 6 ++++-- tools/dockerfile/grpc_artifact_linux_armv7/Dockerfile | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/grpc_artifact_linux_armv6/Dockerfile b/tools/dockerfile/grpc_artifact_linux_armv6/Dockerfile index fb83a5ca6aa..e2c406599dc 100644 --- a/tools/dockerfile/grpc_artifact_linux_armv6/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_armv6/Dockerfile @@ -14,11 +14,13 @@ # Docker file for building gRPC Raspbian binaries +# TODO(https://github.com/grpc/grpc/issues/19199): Move off of this image. FROM quay.io/grpc/raspbian_armv6 # Place any extra build instructions between these commands # Recommend modifying upstream docker image (quay.io/grpc/raspbian_armv6) # for build steps because running them under QEMU is very slow # (https://github.com/kpayson64/armv7hf-debian-qemu) -# RUN [ "cross-build-start" ] -# RUN [ "cross-build-end" ] +RUN [ "cross-build-start" ] +RUN find /usr/local/bin -regex '.*python[0-9]+\.[0-9]+' | xargs -n1 -i{} bash -c "{} -m pip install --upgrade wheel setuptools" +RUN [ "cross-build-end" ] diff --git a/tools/dockerfile/grpc_artifact_linux_armv7/Dockerfile b/tools/dockerfile/grpc_artifact_linux_armv7/Dockerfile index 0b68df52d12..735c2e85b26 100644 --- a/tools/dockerfile/grpc_artifact_linux_armv7/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_armv7/Dockerfile @@ -14,11 +14,13 @@ # Docker file for building gRPC Raspbian binaries +# TODO(https://github.com/grpc/grpc/issues/19199): Move off of this base image. FROM quay.io/grpc/raspbian_armv7 # Place any extra build instructions between these commands # Recommend modifying upstream docker image (quay.io/grpc/raspbian_armv7) # for build steps because running them under QEMU is very slow # (https://github.com/kpayson64/armv7hf-debian-qemu) -# RUN [ "cross-build-start" ] -# RUN [ "cross-build-end" ] +RUN [ "cross-build-start" ] +RUN find /usr/local/bin -regex '.*python[0-9]+\.[0-9]+' | xargs -n1 -i{} bash -c "{} -m pip install --upgrade wheel setuptools" +RUN [ "cross-build-end" ] From 6040249a61020aca939c88a5d2af67a429221d1d Mon Sep 17 00:00:00 2001 From: weiyongji <232589621@qq.com> Date: Sat, 1 Jun 2019 11:31:23 +0800 Subject: [PATCH 199/676] fix a windows compile warning --- .../resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 85f5cd84ca0..7d5215938e3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -231,7 +231,6 @@ class GrpcPolledFdWindows : public GrpcPolledFd { ares_ssize_t TrySendWriteBufSyncNonBlocking() { GPR_ASSERT(write_state_ == WRITE_IDLE); - ares_ssize_t total_sent; DWORD bytes_sent = 0; if (SendWriteBuf(&bytes_sent, nullptr) != 0) { int wsa_last_error = WSAGetLastError(); From a04dcb9da97de4ee928ab772255a4ec8c2048407 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sat, 1 Jun 2019 00:25:11 -0700 Subject: [PATCH 200/676] PHP: Fix ZTS build shutdown segfault --- src/php/ext/grpc/php_grpc.c | 16 +++++++++++----- src/php/ext/grpc/php_grpc.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 74f536ea07b..6d66e790459 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -42,6 +42,8 @@ const zend_function_entry grpc_functions[] = { }; /* }}} */ +ZEND_DECLARE_MODULE_GLOBALS(grpc); + /* {{{ grpc_module_entry */ zend_module_entry grpc_module_entry = { @@ -77,10 +79,13 @@ ZEND_GET_MODULE(grpc) /* {{{ php_grpc_init_globals */ -static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) { - grpc_globals->enable_fork_support = 0; - grpc_globals->poll_strategy = NULL; -} +/* Uncomment this function if you have INI entries + static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) + { + grpc_globals->global_value = 0; + grpc_globals->global_string = NULL; + } +*/ /* }}} */ void create_new_channel( @@ -222,7 +227,6 @@ void apply_ini_settings(TSRMLS_D) { /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(grpc) { - ZEND_INIT_MODULE_GLOBALS(grpc, php_grpc_init_globals, NULL); REGISTER_INI_ENTRIES(); /* Register call error constants */ @@ -406,6 +410,8 @@ PHP_RINIT_FUNCTION(grpc) { */ static PHP_GINIT_FUNCTION(grpc) { grpc_globals->initialized = 0; + grpc_globals->enable_fork_support = 0; + grpc_globals->poll_strategy = NULL; } /* }}} */ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index 2629b1bbd78..1c7973b9ef8 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -70,6 +70,8 @@ ZEND_BEGIN_MODULE_GLOBALS(grpc) char *poll_strategy; ZEND_END_MODULE_GLOBALS(grpc) +ZEND_EXTERN_MODULE_GLOBALS(grpc); + /* In every utility function you add that needs to use variables in php_grpc_globals, call TSRMLS_FETCH(); after declaring other variables used by that function, or better yet, pass in TSRMLS_CC From aa3b2d1e865eae1204ae6339efec1b9338e2ffac Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sat, 1 Jun 2019 00:25:11 -0700 Subject: [PATCH 201/676] PHP: Fix ZTS build shutdown segfault --- src/php/ext/grpc/php_grpc.c | 16 +++++++++++----- src/php/ext/grpc/php_grpc.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 74f536ea07b..6d66e790459 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -42,6 +42,8 @@ const zend_function_entry grpc_functions[] = { }; /* }}} */ +ZEND_DECLARE_MODULE_GLOBALS(grpc); + /* {{{ grpc_module_entry */ zend_module_entry grpc_module_entry = { @@ -77,10 +79,13 @@ ZEND_GET_MODULE(grpc) /* {{{ php_grpc_init_globals */ -static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) { - grpc_globals->enable_fork_support = 0; - grpc_globals->poll_strategy = NULL; -} +/* Uncomment this function if you have INI entries + static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) + { + grpc_globals->global_value = 0; + grpc_globals->global_string = NULL; + } +*/ /* }}} */ void create_new_channel( @@ -222,7 +227,6 @@ void apply_ini_settings(TSRMLS_D) { /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(grpc) { - ZEND_INIT_MODULE_GLOBALS(grpc, php_grpc_init_globals, NULL); REGISTER_INI_ENTRIES(); /* Register call error constants */ @@ -406,6 +410,8 @@ PHP_RINIT_FUNCTION(grpc) { */ static PHP_GINIT_FUNCTION(grpc) { grpc_globals->initialized = 0; + grpc_globals->enable_fork_support = 0; + grpc_globals->poll_strategy = NULL; } /* }}} */ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index 2629b1bbd78..1c7973b9ef8 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -70,6 +70,8 @@ ZEND_BEGIN_MODULE_GLOBALS(grpc) char *poll_strategy; ZEND_END_MODULE_GLOBALS(grpc) +ZEND_EXTERN_MODULE_GLOBALS(grpc); + /* In every utility function you add that needs to use variables in php_grpc_globals, call TSRMLS_FETCH(); after declaring other variables used by that function, or better yet, pass in TSRMLS_CC From 187ef99e66852ff825b4d1762b3150b5f35535d6 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sun, 2 Jun 2019 21:09:34 -0700 Subject: [PATCH 202/676] Bump version to v1.21.3-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 37046f67a83..e0113d48a18 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.2" +version = "1.21.3-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 3fc8b651714..6bc58bf4411 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.2 + version: 1.21.3-pre1 filegroups: - name: alts_proto headers: From f7425cb318c416e13a80a801bc6e5fe09324565a Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sun, 2 Jun 2019 21:10:23 -0700 Subject: [PATCH 203/676] Re-generate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c8d64b7f0c..0067454a2d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.2") +set(PACKAGE_VERSION "1.21.3-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 6d717454fe5..2b150815592 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.2 -CSHARP_VERSION = 1.21.2 +CPP_VERSION = 1.21.3-pre1 +CSHARP_VERSION = 1.21.3-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3fc781b9355..47b18b9b75d 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.2' - version = '0.0.9' + # version = '1.21.3-pre1' + version = '0.0.9-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.2' + grpc_version = '1.21.3-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 220d3af3b4b..ce9a7d6a525 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.2' + version = '1.21.3-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index b49ccb9006a..3f8180c4d3e 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.2' + version = '1.21.3-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 673e7bce88b..6a8a7b89061 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.2' + version = '1.21.3-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 1352c4c612b..1afc2e68623 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.2' + version = '1.21.3-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 64c740e265a..7292aa634eb 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.2 - 1.21.2 + 1.21.3RC1 + 1.21.3RC1 - stable - stable + beta + beta Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 0a70066da99..fcb80876989 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.2"; } +grpc::string Version() { return "1.21.3-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index dd609b57861..f3420552430 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.2.0"; + public const string CurrentAssemblyFileVersion = "1.21.3.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.2"; + public const string CurrentVersion = "1.21.3-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index ee7c7deba2b..0819b58b5f1 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.2 + 1.21.3-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index ba058320ae0..0504ee05855 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.2 +set VERSION=1.21.3-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index c40eeace00e..958f30a5994 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.2' + v = '1.21.3-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 681da2b810a..4ab2203fd09 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.2" +#define GRPC_OBJC_VERSION_STRING @"1.21.3-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 44d99eb284a..20f3f55cf44 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.2" +#define GRPC_OBJC_VERSION_STRING @"1.21.3-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index e76014083f7..48dfde56d86 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.2", + "version": "1.21.3", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 5371146a432..0619b687a5b 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.2" +#define PHP_GRPC_VERSION "1.21.3RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 3af536e9f37..94a507ace4e 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.2""" +__version__ = """1.21.3rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 514df8b0ef4..2ae2edfad44 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 961939cb2ad..19a2283ed55 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 1497d526468..19cefb59977 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 7731b932266..2bc839f13a1 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index d8714f76d5b..c1f396d0bc8 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 2e9d29235bf..4b0438ad4d5 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 715493c169f..7f12f28c47b 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index b31c382f0c2..9ae6bcfe1c7 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.2' + VERSION = '1.21.3.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 46d8d13cebc..1febd620e61 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.2' + VERSION = '1.21.3.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 7299a21a23f..5ff025d1fa1 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.2' +VERSION = '1.21.3rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index b7d5569f8d3..6264bf30779 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.2 +PROJECT_NUMBER = 1.21.3-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 7848ef8f3a3..bb4f9791e90 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.2 +PROJECT_NUMBER = 1.21.3-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From ad103834caf394a93a46fbadbe90ee9cd3bbd58b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Jun 2019 13:55:13 +0200 Subject: [PATCH 204/676] Fix syntax error --- tools/interop_matrix/client_matrix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 6def5fbf286..6733c2f99c6 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -145,7 +145,7 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo(runtimes=['java_oracle8'])), ('v1.19.0', ReleaseInfo(runtimes=['java_oracle8'])), ('v1.20.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.21.0', ReleaseInfo(runtimes=['java_oracle8']))), + ('v1.21.0', ReleaseInfo(runtimes=['java_oracle8'])), ]), 'python': OrderedDict([ From 04a3d9c2aa915fce17a4182b6bfd45b1d61e40c5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Jun 2019 08:49:29 -0700 Subject: [PATCH 205/676] build failure fix --- 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 cfd67b99f34..ac9acbce730 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -249,7 +249,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): configs=['dbg'], platforms=['macos'], labels=['basictests', 'multilang'], - extra_args=extra_args + os.getenv('GRPC_OBJC_TEST_EXTRA_ARGS', '.*'), + extra_args=extra_args + [os.getenv('GRPC_OBJC_TEST_EXTRA_ARGS', '.*')], inner_jobs=inner_jobs, timeout_seconds=_OBJC_RUNTESTS_TIMEOUT) From 06f38432816613becfd5c5093a998c7cc76206ea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 26 Apr 2019 05:11:06 -0400 Subject: [PATCH 206/676] refresh of interop matrix testcases --- tools/interop_matrix/testcases/cxx__master | 58 +++++++++----- tools/interop_matrix/testcases/go__master | 76 ++++++++++++++----- tools/interop_matrix/testcases/java__master | 76 ++++++++++++++----- tools/interop_matrix/testcases/php__master | 40 +++++----- tools/interop_matrix/testcases/python__master | 2 +- tools/interop_matrix/testcases/ruby__master | 40 +++++----- 6 files changed, 196 insertions(+), 96 deletions(-) diff --git a/tools/interop_matrix/testcases/cxx__master b/tools/interop_matrix/testcases/cxx__master index 629da1afd0d..eb43a15df7d 100755 --- a/tools/interop_matrix/testcases/cxx__master +++ b/tools/interop_matrix/testcases/cxx__master @@ -1,20 +1,40 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_cxx:78de6f80-524d-4bc9-bfb2-f00c24ceafed}" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_cxx:e5d09e32-2654-4e12-9a2e-1f0715768d1a}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" diff --git a/tools/interop_matrix/testcases/go__master b/tools/interop_matrix/testcases/go__master index a7f83ae1693..ce61e14e3a1 100755 --- a/tools/interop_matrix/testcases/go__master +++ b/tools/interop_matrix/testcases/go__master @@ -1,20 +1,58 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_go:dd8fbf3a-4964-4387-9997-5dadeea09835}" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_go:27323929-b77f-4b15-9fe5-21403a49fa31}" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" diff --git a/tools/interop_matrix/testcases/java__master b/tools/interop_matrix/testcases/java__master index 95a9c2834f4..ac6b9aed5e6 100755 --- a/tools/interop_matrix/testcases/java__master +++ b/tools/interop_matrix/testcases/java__master @@ -1,20 +1,58 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_java:a764b50c-1788-4387-9b9e-5cfa93927006}" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_java:45b54245-f0e4-4e80-ad47-03826412871f}" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" diff --git a/tools/interop_matrix/testcases/php__master b/tools/interop_matrix/testcases/php__master index f99cb176212..3d7e99728aa 100755 --- a/tools/interop_matrix/testcases/php__master +++ b/tools/interop_matrix/testcases/php__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_php:b290f404-9940-4968-8fc2-19f5291c8eb7}" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_php:e00a3b45-27f0-4143-8c23-128cb4ffc46a}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" diff --git a/tools/interop_matrix/testcases/python__master b/tools/interop_matrix/testcases/python__master index 39e160188c7..0fc23810d0e 100755 --- a/tools/interop_matrix/testcases/python__master +++ b/tools/interop_matrix/testcases/python__master @@ -1,7 +1,7 @@ #!/bin/bash # DO NOT MODIFY # This file is generated by run_interop_tests.py/create_testcases.sh -echo "Testing ${docker_image:=grpc_interop_python:4fa5bb4b-5d57-4882-8c8e-551fb899b86a}" +echo "Testing ${docker_image:=grpc_interop_python:8f586cb2-054e-4653-91a4-3ffdc94e71fc}" docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true\"" docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true\"" docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true\"" diff --git a/tools/interop_matrix/testcases/ruby__master b/tools/interop_matrix/testcases/ruby__master index 784ba689f6f..670171f3dbb 100755 --- a/tools/interop_matrix/testcases/ruby__master +++ b/tools/interop_matrix/testcases/ruby__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_ruby:6bd1f0eb-51a4-4ad8-861c-1cbd7a929f33}" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_ruby:e60da8f6-d7e0-47d3-8bfe-330ce76077b4}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" From 7898ec24dd7e29730d8dded0813d13b9db8ef030 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 14:33:33 -0400 Subject: [PATCH 207/676] fix client_matrix.py for php and ruby --- tools/interop_matrix/client_matrix.py | 66 ++++++++++----------- tools/interop_matrix/testcases/php__v1.0.1 | 20 +++++++ tools/interop_matrix/testcases/ruby__v1.1.4 | 20 +++++++ 3 files changed, 73 insertions(+), 33 deletions(-) create mode 100755 tools/interop_matrix/testcases/php__v1.0.1 create mode 100755 tools/interop_matrix/testcases/ruby__v1.1.4 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 9144be15443..57684a1af7d 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -195,22 +195,22 @@ LANG_RELEASE_MATRIX = { 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', ], testcases_file='ruby__v1.0.1')), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), - ('v1.7.2', ReleaseInfo()), - ('v1.8.0', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.1', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.0', ReleaseInfo()), - ('v1.14.1', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.0', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), + ('v1.1.4', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.2.5', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.3.9', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.4.2', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.6.6', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.7.2', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.8.0', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.9.1', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.10.1', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.11.1', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.12.0', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.13.0', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.14.1', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.15.0', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.16.0', ReleaseInfo(testcases_file='ruby__v1.1.4')), + ('v1.17.1', ReleaseInfo(testcases_file='ruby__v1.1.4')), ('v1.18.0', ReleaseInfo(patch=[ 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', @@ -223,23 +223,23 @@ LANG_RELEASE_MATRIX = { ]), 'php': OrderedDict([ - ('v1.0.1', ReleaseInfo()), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), - ('v1.7.2', ReleaseInfo()), - ('v1.8.0', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.1', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.0', ReleaseInfo()), - ('v1.14.1', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.0', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), + ('v1.0.1', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.1.4', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.2.5', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.3.9', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.4.2', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.6.6', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.7.2', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.8.0', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.9.1', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.10.1', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.11.1', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.12.0', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.13.0', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.14.1', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.15.0', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')), + ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.18.0', ReleaseInfo()), # TODO:https://github.com/grpc/grpc/issues/18264 # Error in above issues needs to be resolved. diff --git a/tools/interop_matrix/testcases/php__v1.0.1 b/tools/interop_matrix/testcases/php__v1.0.1 new file mode 100755 index 00000000000..f99cb176212 --- /dev/null +++ b/tools/interop_matrix/testcases/php__v1.0.1 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_php:b290f404-9940-4968-8fc2-19f5291c8eb7}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "src/php/bin/interop_client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" diff --git a/tools/interop_matrix/testcases/ruby__v1.1.4 b/tools/interop_matrix/testcases/ruby__v1.1.4 new file mode 100755 index 00000000000..784ba689f6f --- /dev/null +++ b/tools/interop_matrix/testcases/ruby__v1.1.4 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_ruby:6bd1f0eb-51a4-4ad8-861c-1cbd7a929f33}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_rvm.sh ruby src/ruby/pb/test/client.rb --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From fc0556ef03e64f2f15ce03c34bd8c34d39c4a519 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 14:43:01 -0400 Subject: [PATCH 208/676] fix c++ client_matrix.py --- tools/interop_matrix/client_matrix.py | 38 +++++++++++----------- tools/interop_matrix/testcases/cxx__v1.0.1 | 20 ++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) create mode 100755 tools/interop_matrix/testcases/cxx__v1.0.1 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 57684a1af7d..68426141dc5 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -77,25 +77,25 @@ class ReleaseInfo: LANG_RELEASE_MATRIX = { 'cxx': OrderedDict([ - ('v1.0.1', ReleaseInfo()), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), - ('v1.7.2', ReleaseInfo()), - ('v1.8.0', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.1', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.0', ReleaseInfo()), - ('v1.14.1', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.0', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), - ('v1.18.0', ReleaseInfo()), - ('v1.19.0', ReleaseInfo()), + ('v1.0.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.1.4', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.2.5', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.3.9', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.4.2', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.6.6', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.7.2', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.8.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.9.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.10.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.11.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.12.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.13.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.14.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.15.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.16.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.17.1', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.18.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), + ('v1.19.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), ('v1.20.0', ReleaseInfo()), ]), 'go': diff --git a/tools/interop_matrix/testcases/cxx__v1.0.1 b/tools/interop_matrix/testcases/cxx__v1.0.1 new file mode 100755 index 00000000000..629da1afd0d --- /dev/null +++ b/tools/interop_matrix/testcases/cxx__v1.0.1 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_cxx:78de6f80-524d-4bc9-bfb2-f00c24ceafed}" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From 9c6830a3f5edf000a4c1060a10b5eab385a98015 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 14:46:53 -0400 Subject: [PATCH 209/676] fix java client_matrix.py --- tools/interop_matrix/client_matrix.py | 40 ++++++++++----------- tools/interop_matrix/testcases/java__v1.0.3 | 20 +++++++++++ 2 files changed, 40 insertions(+), 20 deletions(-) create mode 100755 tools/interop_matrix/testcases/java__v1.0.3 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 68426141dc5..f4b05057ab3 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -124,26 +124,26 @@ LANG_RELEASE_MATRIX = { ]), 'java': OrderedDict([ - ('v1.0.3', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.1.2', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.2.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.3.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.4.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.5.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.6.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.7.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.8.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.9.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.10.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.11.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.12.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.13.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.14.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.15.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.16.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.17.1', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.18.0', ReleaseInfo(runtimes=['java_oracle8'])), - ('v1.19.0', ReleaseInfo(runtimes=['java_oracle8'])), + ('v1.0.3', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.1.2', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.2.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.3.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.4.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.5.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.6.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.7.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.8.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.9.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.10.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.11.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.12.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.13.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.14.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.15.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.16.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.17.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.18.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.19.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), ('v1.20.0', ReleaseInfo(runtimes=['java_oracle8'])), ('v1.21.0', ReleaseInfo(runtimes=['java_oracle8'])), ]), diff --git a/tools/interop_matrix/testcases/java__v1.0.3 b/tools/interop_matrix/testcases/java__v1.0.3 new file mode 100755 index 00000000000..95a9c2834f4 --- /dev/null +++ b/tools/interop_matrix/testcases/java__v1.0.3 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_java:a764b50c-1788-4387-9b9e-5cfa93927006}" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From cc0fc17301d5aef9e4f27b3814b29c7b51a85b9e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 May 2019 14:51:44 -0400 Subject: [PATCH 210/676] fix go client_matrix.py --- tools/interop_matrix/client_matrix.py | 38 +++++++++++------------ tools/interop_matrix/testcases/go__v1.0.5 | 20 ++++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-) create mode 100755 tools/interop_matrix/testcases/go__v1.0.5 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index f4b05057ab3..38cd94553a4 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -100,25 +100,25 @@ LANG_RELEASE_MATRIX = { ]), 'go': OrderedDict([ - ('v1.0.5', ReleaseInfo(runtimes=['go1.8'])), - ('v1.2.1', ReleaseInfo(runtimes=['go1.8'])), - ('v1.3.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.4.2', ReleaseInfo(runtimes=['go1.8'])), - ('v1.5.2', ReleaseInfo(runtimes=['go1.8'])), - ('v1.6.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.7.4', ReleaseInfo(runtimes=['go1.8'])), - ('v1.8.2', ReleaseInfo(runtimes=['go1.8'])), - ('v1.9.2', ReleaseInfo(runtimes=['go1.8'])), - ('v1.10.1', ReleaseInfo(runtimes=['go1.8'])), - ('v1.11.3', ReleaseInfo(runtimes=['go1.8'])), - ('v1.12.2', ReleaseInfo(runtimes=['go1.8'])), - ('v1.13.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.14.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.15.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.16.0', ReleaseInfo(runtimes=['go1.8'])), - ('v1.17.0', ReleaseInfo(runtimes=['go1.11'])), - ('v1.18.0', ReleaseInfo(runtimes=['go1.11'])), - ('v1.19.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.0.5', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.2.1', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.3.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.4.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.5.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.6.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.7.4', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.8.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.9.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.10.1', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.11.3', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.12.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.13.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.14.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.15.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.16.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.17.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), + ('v1.18.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), + ('v1.19.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), ('v1.20.0', ReleaseInfo(runtimes=['go1.11'])), ('v1.21.0', ReleaseInfo(runtimes=['go1.11'])), ]), diff --git a/tools/interop_matrix/testcases/go__v1.0.5 b/tools/interop_matrix/testcases/go__v1.0.5 new file mode 100755 index 00000000000..a7f83ae1693 --- /dev/null +++ b/tools/interop_matrix/testcases/go__v1.0.5 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_go:dd8fbf3a-4964-4387-9997-5dadeea09835}" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From 62b35286a79464cec036597f5d292b9f57ed4764 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 24 May 2019 03:12:22 -0400 Subject: [PATCH 211/676] yapf --- tools/interop_matrix/client_matrix.py | 126 +++++++++++++++++--------- 1 file changed, 83 insertions(+), 43 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 38cd94553a4..43002c3b222 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -99,51 +99,91 @@ LANG_RELEASE_MATRIX = { ('v1.20.0', ReleaseInfo()), ]), 'go': - OrderedDict([ - ('v1.0.5', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.2.1', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.3.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.4.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.5.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.6.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.7.4', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.8.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.9.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.10.1', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.11.3', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.12.2', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.13.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.14.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.15.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.16.0', ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), - ('v1.17.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), - ('v1.18.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), - ('v1.19.0', ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), - ('v1.20.0', ReleaseInfo(runtimes=['go1.11'])), - ('v1.21.0', ReleaseInfo(runtimes=['go1.11'])), - ]), + OrderedDict( + [ + ('v1.0.5', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.2.1', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.3.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.4.2', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.5.2', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.6.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.7.4', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.8.2', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.9.2', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.10.1', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.11.3', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.12.2', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.13.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.14.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.15.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.16.0', + ReleaseInfo(runtimes=['go1.8'], testcases_file='go__v1.0.5')), + ('v1.17.0', + ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), + ('v1.18.0', + ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), + ('v1.19.0', + ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')), + ('v1.20.0', ReleaseInfo(runtimes=['go1.11'])), + ('v1.21.0', ReleaseInfo(runtimes=['go1.11'])), + ]), 'java': OrderedDict([ - ('v1.0.3', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.1.2', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.2.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.3.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.4.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.5.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.6.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.7.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.8.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.9.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.10.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.11.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.12.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.13.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.14.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.15.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.16.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.17.1', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.18.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), - ('v1.19.0', ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.0.3', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.1.2', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.2.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.3.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.4.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.5.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.6.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.7.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.8.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.9.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.10.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.11.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.12.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.13.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.14.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.15.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.16.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.17.1', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.18.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), + ('v1.19.0', + ReleaseInfo(runtimes=['java_oracle8'], testcases_file='java__v1.0.3')), ('v1.20.0', ReleaseInfo(runtimes=['java_oracle8'])), ('v1.21.0', ReleaseInfo(runtimes=['java_oracle8'])), ]), From 97921f5d77f50496660bd3cc230df6a0bd6140e1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Jun 2019 08:16:32 -0400 Subject: [PATCH 212/676] add comments to interop scripts --- tools/interop_matrix/run_interop_matrix_tests.py | 2 ++ tools/run_tests/run_interop_tests.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 3f92c8e6641..120ba08b465 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -86,6 +86,8 @@ argp.add_argument( type=str, nargs='?', help='Upload test results to a specified BQ table.') +# Requests will be routed through specified VIP by default. +# See go/grpc-interop-tests (internal-only) for details. argp.add_argument( '--server_host', default='74.125.206.210', diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index cc6901bdebe..108f91e8383 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -1152,7 +1152,8 @@ def aggregate_http2_results(stdout): } -# A dictionary of prod servers to test. +# A dictionary of prod servers to test against. +# See go/grpc-interop-tests (internal-only) for details. prod_servers = { 'default': 'grpc-test.sandbox.googleapis.com', 'gateway_v4': 'grpc-test4.sandbox.googleapis.com', From c15665399735ae4de59d59606aeee2603a54bdc8 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 3 Jun 2019 10:38:37 -0700 Subject: [PATCH 213/676] Add listner fd as part of the external connection parameters --- include/grpcpp/server_builder_impl.h | 1 + src/core/lib/iomgr/tcp_server.h | 4 +++- src/core/lib/iomgr/tcp_server_posix.cc | 3 ++- src/cpp/server/external_connection_acceptor_impl.cc | 2 +- test/cpp/end2end/port_sharing_end2end_test.cc | 8 ++++++-- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 0de72cc397c..7f85e807d07 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -67,6 +67,7 @@ class CallbackGenericService; class ExternalConnectionAcceptor { public: struct NewConnectionParameters { + int listener_fd = -1; int fd = -1; ByteBuffer read_buffer; // data intended for the grpc server }; diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 774f06ee17a..0d16b66230f 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -41,6 +41,7 @@ typedef struct grpc_tcp_server_acceptor { unsigned fd_index; /* Data when the connection is passed to tcp_server from external. */ bool external_connection; + int listener_fd; grpc_byte_buffer* pending_data; } grpc_tcp_server_acceptor; @@ -55,7 +56,8 @@ namespace grpc_core { class TcpServerFdHandler { public: virtual ~TcpServerFdHandler() = default; - virtual void Handle(int fd, grpc_byte_buffer* pending_read) GRPC_ABSTRACT; + virtual void Handle(int listener_fd, int fd, + grpc_byte_buffer* pending_read) GRPC_ABSTRACT; GRPC_ABSTRACT_BASE_CLASS; }; diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 001f786b65d..689c005bf0d 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -572,7 +572,7 @@ class ExternalConnectionHandler : public grpc_core::TcpServerFdHandler { explicit ExternalConnectionHandler(grpc_tcp_server* s) : s_(s) {} // TODO(yangg) resolve duplicate code with on_read - void Handle(int fd, grpc_byte_buffer* buf) override { + void Handle(int listener_fd, int fd, grpc_byte_buffer* buf) override { grpc_pollset* read_notifier_pollset; grpc_resolved_address addr; char* addr_str; @@ -606,6 +606,7 @@ class ExternalConnectionHandler : public grpc_core::TcpServerFdHandler { acceptor->port_index = -1; acceptor->fd_index = -1; acceptor->external_connection = true; + acceptor->listener_fd = listener_fd; acceptor->pending_data = buf; s_->on_accept_cb(s_->on_accept_cb_arg, grpc_tcp_create(fdobj, s_->channel_args, addr_str), diff --git a/src/cpp/server/external_connection_acceptor_impl.cc b/src/cpp/server/external_connection_acceptor_impl.cc index afc90679398..7f0e2dcfe93 100644 --- a/src/cpp/server/external_connection_acceptor_impl.cc +++ b/src/cpp/server/external_connection_acceptor_impl.cc @@ -71,7 +71,7 @@ void ExternalConnectionAcceptorImpl::HandleNewConnection( return; } if (handler_) { - handler_->Handle(p->fd, p->read_buffer.c_buffer()); + handler_->Handle(p->listener_fd, p->fd, p->read_buffer.c_buffer()); } } diff --git a/test/cpp/end2end/port_sharing_end2end_test.cc b/test/cpp/end2end/port_sharing_end2end_test.cc index a2b9417d172..7ea5c046dc6 100644 --- a/test/cpp/end2end/port_sharing_end2end_test.cc +++ b/test/cpp/end2end/port_sharing_end2end_test.cc @@ -159,6 +159,8 @@ class TestTcpServer { gpr_log(GPR_INFO, "Got incoming connection! from %s", peer); gpr_free(peer); EXPECT_FALSE(acceptor->external_connection); + listener_fd_ = grpc_tcp_server_port_fd( + acceptor->from_server, acceptor->port_index, acceptor->fd_index); gpr_free(acceptor); grpc_tcp_destroy_and_release_fd(tcp, &fd_, &on_fd_released_); } @@ -166,6 +168,7 @@ class TestTcpServer { void OnFdReleased(grpc_error* err) { EXPECT_EQ(GRPC_ERROR_NONE, err); experimental::ExternalConnectionAcceptor::NewConnectionParameters p; + p.listener_fd = listener_fd_; p.fd = fd_; if (queue_data_) { char buf[1024]; @@ -176,14 +179,15 @@ class TestTcpServer { Slice data(buf, read_bytes); p.read_buffer = ByteBuffer(&data, 1); } - gpr_log(GPR_INFO, "Handing off fd %d with data size %d", fd_, - static_cast(p.read_buffer.Length())); + gpr_log(GPR_INFO, "Handing off fd %d with data size %d from listener fd %d", + fd_, static_cast(p.read_buffer.Length()), listener_fd_); connection_acceptor_->HandleNewConnection(&p); } std::mutex mu_; bool shutdown_; + int listener_fd_; int fd_; bool queue_data_; From 8e159df5e8ddf647675f1e17af97120a51d50eca Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Sat, 1 Jun 2019 18:59:41 -0700 Subject: [PATCH 214/676] Bump to version 1.21.3 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index e0113d48a18..af1d7847cef 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.3-pre1" +version = "1.21.3" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 6bc58bf4411..d9a72738f48 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.3-pre1 + version: 1.21.3 filegroups: - name: alts_proto headers: From 961ca7ec9d9a5812e06e1605b6349a2f284e48d4 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 3 Jun 2019 10:49:11 -0700 Subject: [PATCH 215/676] Re-generate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0067454a2d7..1f01e790264 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.3-pre1") +set(PACKAGE_VERSION "1.21.3") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 2b150815592..fd29aa3fc73 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.3-pre1 -CSHARP_VERSION = 1.21.3-pre1 +CPP_VERSION = 1.21.3 +CSHARP_VERSION = 1.21.3 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 47b18b9b75d..1fdd6423a7e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.3-pre1' - version = '0.0.9-pre1' + # version = '1.21.3' + version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.3-pre1' + grpc_version = '1.21.3' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ce9a7d6a525..061d3a27504 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.3-pre1' + version = '1.21.3' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 3f8180c4d3e..c38719b7d52 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.3-pre1' + version = '1.21.3' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 6a8a7b89061..20f93164969 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.3-pre1' + version = '1.21.3' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 1afc2e68623..e268a8b21aa 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.3-pre1' + version = '1.21.3' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 7292aa634eb..f03c4e694d8 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.3RC1 - 1.21.3RC1 + 1.21.3 + 1.21.3 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index fcb80876989..98c1ba34470 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.3-pre1"; } +grpc::string Version() { return "1.21.3"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index f3420552430..3d4bdd9ee78 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.3-pre1"; + public const string CurrentVersion = "1.21.3"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 0819b58b5f1..949b683ccb5 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.3-pre1 + 1.21.3 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 0504ee05855..a371568fab8 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.3-pre1 +set VERSION=1.21.3 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 958f30a5994..c4b588824de 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.3-pre1' + v = '1.21.3' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 4ab2203fd09..20cf2ac4811 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.3-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.3" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 20f3f55cf44..0aa72ca70da 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.3-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.3" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 0619b687a5b..d401a7d2095 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.3RC1" +#define PHP_GRPC_VERSION "1.21.3" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 94a507ace4e..ea4600f7d0a 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.3rc1""" +__version__ = """1.21.3""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2ae2edfad44..ad12bf478ed 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 19a2283ed55..73ecfb1c3c7 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 19cefb59977..c26d3697972 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 2bc839f13a1..b434ba9422e 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index c1f396d0bc8..4516db48837 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 4b0438ad4d5..735c66a9081 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 7f12f28c47b..ab2507f2c94 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 9ae6bcfe1c7..55b26e434a6 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.3.pre1' + VERSION = '1.21.3' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 1febd620e61..4effc70d476 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.3.pre1' + VERSION = '1.21.3' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 5ff025d1fa1..bb7110142ae 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.3rc1' +VERSION = '1.21.3' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 6264bf30779..15f82e95211 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.3-pre1 +PROJECT_NUMBER = 1.21.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index bb4f9791e90..63614418486 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.3-pre1 +PROJECT_NUMBER = 1.21.3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 21f512eddf243b05f650431b942758b38582b518 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 3 Jun 2019 11:22:30 -0700 Subject: [PATCH 216/676] Make a copy of received headers --- src/objective-c/GRPCClient/GRPCCall.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 71b03f15f17..5a3440f84ed 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -714,7 +714,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { @synchronized(strongSelf) { - strongSelf.responseHeaders = headers; + // it is ok to set nil because headers are only received once + strongSelf.responseHeaders = nil; + // copy the header so that the GRPCOpRecvMetadata object may be dealloc'ed + NSDictionary *copiedHeaders = [[NSDictionary alloc] initWithDictionary:headers + copyItems:YES]; + strongSelf.responseHeaders = copiedHeaders; strongSelf->_pendingCoreRead = NO; [strongSelf maybeStartNextRead]; } From 6ced31ee8963be25506e16d8978e4cfd5ba18957 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 3 Jun 2019 13:10:12 -0700 Subject: [PATCH 217/676] resolve review comments --- test/cpp/end2end/port_sharing_end2end_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/end2end/port_sharing_end2end_test.cc b/test/cpp/end2end/port_sharing_end2end_test.cc index 7ea5c046dc6..4f30290d815 100644 --- a/test/cpp/end2end/port_sharing_end2end_test.cc +++ b/test/cpp/end2end/port_sharing_end2end_test.cc @@ -187,13 +187,13 @@ class TestTcpServer { std::mutex mu_; bool shutdown_; - int listener_fd_; - int fd_; - bool queue_data_; + int listener_fd_ = -1; + int fd_ = -1; + bool queue_data_ = false; grpc_closure on_fd_released_; std::thread running_thread_; - int port_; + int port_ = -1; grpc::string address_; std::unique_ptr connection_acceptor_; From 91eb1141a98d374ebdad56e0b139aebf3ac12535 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 3 Jun 2019 13:16:48 -0700 Subject: [PATCH 218/676] Ask server to skip cancel check --- test/cpp/end2end/end2end_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 983714c044a..a8592fd97c2 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1875,6 +1875,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithDeadline) { MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; + request.mutable_param()->set_skip_cancelled_check(true); EchoResponse response; ClientContext context; const int delay = 100; @@ -1898,6 +1899,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginWithCancel) { MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; + request.mutable_param()->set_skip_cancelled_check(true); EchoResponse response; ClientContext context; const int delay = 100; From b0ef377ebdfb1b4ea4ea7b5e4910d163140dc8e1 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Mon, 3 Jun 2019 09:22:08 -0700 Subject: [PATCH 219/676] Fixed erase() method by changing RemoveRecursive() to return a new iterator to the successor in addition to the new root. Both are returned as a single pair --- src/core/lib/gprpp/map.h | 49 ++++++++++++++++------------- test/core/gprpp/map_test.cc | 62 ++++++++++++++++++++++++------------- 2 files changed, 69 insertions(+), 42 deletions(-) diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h index b210c26cbff..525c25347f4 100644 --- a/src/core/lib/gprpp/map.h +++ b/src/core/lib/gprpp/map.h @@ -112,7 +112,10 @@ class Map { // inserted entry and the second value being the new root of the subtree // after a rebalance Pair InsertRecursive(Entry* root, value_type&& p); - static Entry* RemoveRecursive(Entry* root, const key_type& k); + // Returns a pair with the first value being an iterator pointing to the + // successor of the deleted entry and the second value being the new root of + // the subtree after a rebalance + Pair RemoveRecursive(Entry* root, const key_type& k); // Return 0 if lhs = rhs // 1 if lhs > rhs // -1 if lhs < rhs @@ -233,10 +236,10 @@ typename Map::iterator Map::erase( iterator iter) { if (iter == end()) return iter; key_type& del_key = iter->first; - iter++; - root_ = RemoveRecursive(root_, del_key); + Pair ret = RemoveRecursive(root_, del_key); + root_ = ret.second; size_--; - return iter; + return ret.first; } template @@ -373,34 +376,38 @@ Map::RebalanceTreeAfterDeletion(Entry* root) { } template -typename Map::Entry* Map::RemoveRecursive( - Entry* root, const key_type& k) { - if (root == nullptr) return root; +typename ::grpc_core::Pair::iterator, + typename Map::Entry*> +Map::RemoveRecursive(Entry* root, const key_type& k) { + Pair ret = MakePair(end(), root); + if (root == nullptr) return ret; int comp = CompareKeys(root->pair.first, k); if (comp > 0) { - root->left = RemoveRecursive(root->left, k); + ret = RemoveRecursive(root->left, k); + root->left = ret.second; } else if (comp < 0) { - root->right = RemoveRecursive(root->right, k); + ret = RemoveRecursive(root->right, k); + root->right = ret.second; } else { - Entry* ret; + Entry* entry; + Entry* successor = InOrderSuccessor(root); if (root->left == nullptr) { - ret = root->right; + entry = root->right; Delete(root); - return ret; + return MakePair(iterator(this, successor), entry); } else if (root->right == nullptr) { - ret = root->left; + entry = root->left; Delete(root); - return ret; + return MakePair(iterator(this, successor), entry); } else { - ret = root->right; - while (ret->left != nullptr) { - ret = ret->left; - } - root->pair.swap(ret->pair); - root->right = RemoveRecursive(root->right, ret->pair.first); + entry = successor; + root->pair.swap(entry->pair); + ret = RemoveRecursive(root->right, entry->pair.first); + root->right = ret.second; + ret.first = iterator(this, root); } } - return RebalanceTreeAfterDeletion(root); + return MakePair(ret.first, RebalanceTreeAfterDeletion(root)); } template diff --git a/test/core/gprpp/map_test.cc b/test/core/gprpp/map_test.cc index e70bf38f111..6e70a2a2ac2 100644 --- a/test/core/gprpp/map_test.cc +++ b/test/core/gprpp/map_test.cc @@ -17,7 +17,9 @@ */ #include "src/core/lib/gprpp/map.h" + #include + #include "include/grpc/support/string_util.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/memory.h" @@ -319,43 +321,49 @@ TEST_F(MapTest, MapRandomInsertions) { // Test Map iterator TEST_F(MapTest, Iteration) { Map test_map; - for (int i = 0; i < 5; i++) { + for (int i = 4; i >= 0; --i) { test_map.emplace(kKeys[i], Payload(i)); } - int count = 0; - for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { - EXPECT_EQ(iter->second.data(), count); - count++; + auto it = test_map.begin(); + for (int i = 0; i < 5; ++i) { + ASSERT_NE(it, test_map.end()); + EXPECT_STREQ(kKeys[i], it->first); + EXPECT_EQ(i, it->second.data()); + ++it; } - EXPECT_EQ(count, 5); + EXPECT_EQ(it, test_map.end()); } // Test Map iterator with unique ptr payload TEST_F(MapTest, IterationWithUniquePtrValue) { Map, StringLess> test_map; - for (int i = 0; i < 5; i++) { + for (int i = 4; i >= 0; --i) { test_map.emplace(kKeys[i], MakeUnique(i)); } - int count = 0; - for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { - EXPECT_EQ(iter->second->data(), count); - count++; + auto it = test_map.begin(); + for (int i = 0; i < 5; ++i) { + ASSERT_NE(it, test_map.end()); + EXPECT_STREQ(kKeys[i], it->first); + EXPECT_EQ(i, it->second->data()); + ++it; } - EXPECT_EQ(count, 5); + EXPECT_EQ(it, test_map.end()); } // Test Map iterator with unique ptr to char key TEST_F(MapTest, IterationWithUniquePtrKey) { Map, Payload, StringLess> test_map; - for (int i = 0; i < 5; i++) { + for (int i = 4; i >= 0; --i) { test_map.emplace(CopyString(kKeys[i]), Payload(i)); } - int count = 0; - for (auto iter = test_map.begin(); iter != test_map.end(); iter++) { - EXPECT_EQ(iter->second.data(), count); - count++; + auto it = test_map.begin(); + for (int i = 0; i < 5; ++i) { + ASSERT_NE(it, test_map.end()); + EXPECT_STREQ(kKeys[i], it->first.get()); + EXPECT_EQ(i, it->second.data()); + ++it; } - EXPECT_EQ(count, 5); + EXPECT_EQ(it, test_map.end()); } // Test removing entries while iterating the map @@ -367,11 +375,23 @@ TEST_F(MapTest, EraseUsingIterator) { int count = 0; for (auto iter = test_map.begin(); iter != test_map.end();) { EXPECT_EQ(iter->second.data(), count); - iter = test_map.erase(iter); - count++; + if (count % 2 == 1) { + iter = test_map.erase(iter); + } else { + ++iter; + } + ++count; } EXPECT_EQ(count, 5); - EXPECT_TRUE(test_map.empty()); + auto it = test_map.begin(); + for (int i = 0; i < 5; ++i) { + if (i % 2 == 0) { + EXPECT_STREQ(kKeys[i], it->first); + EXPECT_EQ(i, it->second.data()); + ++it; + } + } + EXPECT_EQ(it, test_map.end()); } // Random ops on a Map with Integer key of Payload value, From 58771fa12adada9b282ed8729f25eac365571f7e Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Mon, 3 Jun 2019 22:08:40 -0700 Subject: [PATCH 220/676] Fix cfstream_test flake Ask server to skip cancel check in network flap test. --- test/cpp/end2end/cfstream_test.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index 59cf98ffc20..613bc1d0b09 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -341,7 +341,9 @@ TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { // Channel should be in READY state after we send some RPCs for (int i = 0; i < 10; ++i) { - SendAsyncRpc(stub); + RequestParams param; + param.set_skip_cancelled_check(true); + SendAsyncRpc(stub, param); ++rpcs_sent; } EXPECT_TRUE(WaitForChannelReady(channel.get())); @@ -374,7 +376,9 @@ TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { }); for (int i = 0; i < 100; ++i) { - SendAsyncRpc(stub); + RequestParams param; + param.set_skip_cancelled_check(true); + SendAsyncRpc(stub, param); std::this_thread::sleep_for(std::chrono::milliseconds(10)); ++rpcs_sent; } From 9fdc46aa0849428768635dbc9f3485d51c9afd48 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Jun 2019 07:22:24 -0400 Subject: [PATCH 221/676] php interop client: construct channel target like other languages do --- src/php/tests/interop/interop_client.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 19cbf21bc2b..e4750475dc5 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -530,12 +530,7 @@ function _makeStub($args) throw new Exception('Missing argument: --test_case is required'); } - if ($args['server_port'] === '443') { - $server_address = $args['server_host']; - } else { - $server_address = $args['server_host'].':'.$args['server_port']; - } - + $server_address = $args['server_host'].':'.$args['server_port']; $test_case = $args['test_case']; $host_override = ''; From 15cae38cbd38f06846c15df437a901fe70662a37 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Jun 2019 10:27:59 -0400 Subject: [PATCH 222/676] remove port suffix from JWT audience --- src/php/lib/Grpc/BaseStub.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index fe81e377610..1d2c30341dd 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -199,6 +199,13 @@ class BaseStub */ private function _get_jwt_aud_uri($method) { + // TODO(jtattermusch): This is not the correct implementation + // of extracting JWT "aud" claim. We should rely on + // grpc_metadata_credentials_plugin which + // also provides the correct value of "aud" claim + // in the grpc_auth_metadata_context.service_url field. + // Trying to do the construction of "aud" field ourselves + // is bad. $last_slash_idx = strrpos($method, '/'); if ($last_slash_idx === false) { throw new \InvalidArgumentException( @@ -213,6 +220,12 @@ class BaseStub $hostname = $this->hostname; } + // Remove the port if it is 443 + // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/lib/security/transport/client_auth_filter.cc#L205 + if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) { + $hostname = substr($hostname, 0, -4); + } + return 'https://'.$hostname.$service_name; } From e8cb29dd1ebb02867d0f493d4490ff728c440c20 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Jun 2019 09:47:29 -0400 Subject: [PATCH 223/676] allow dots in metadata keys --- src/php/lib/Grpc/BaseStub.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index fe81e377610..d2f293257ce 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -228,10 +228,10 @@ class BaseStub { $metadata_copy = []; foreach ($metadata as $key => $value) { - if (!preg_match('/^[A-Za-z\d_-]+$/', $key)) { + if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) { throw new \InvalidArgumentException( 'Metadata keys must be nonempty strings containing only '. - 'alphanumeric characters, hyphens and underscores' + 'alphanumeric characters, hyphens, underscores and dots' ); } $metadata_copy[strtolower($key)] = $value; From c0dd83e9a0fb603731454745954e01637701c8d8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 4 Jun 2019 11:12:23 -0700 Subject: [PATCH 224/676] Add documentation about CallCredentials restriction --- src/python/grpcio/grpc/__init__.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 6175180e92a..f0c198db66d 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -584,6 +584,9 @@ class ChannelCredentials(object): class CallCredentials(object): """An encapsulation of the data required to assert an identity over a call. + A CallCredentials has to be used with secure Channel, otherwise the + metadata will not be transmitted to the server. + A CallCredentials may be composed with ChannelCredentials to always assert identity for every call over that Channel. @@ -682,7 +685,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): for the RPC. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -714,7 +718,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -746,7 +751,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -781,7 +787,8 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. If None, the timeout is considered infinite. metadata: An optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -816,7 +823,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. If None, the timeout is considered infinite. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -849,7 +857,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. If None, the timeout is considered infinite. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -881,7 +890,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. If None, the timeout is considered infinite. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. @@ -916,7 +926,8 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)): the RPC. If not specified, the timeout is considered infinite. metadata: Optional :term:`metadata` to be transmitted to the service-side of the RPC. - credentials: An optional CallCredentials for the RPC. + credentials: An optional CallCredentials for the RPC. Only valid for + secure Channel. wait_for_ready: This is an EXPERIMENTAL argument. An optional flag to enable wait for ready mechanism compression: An element of grpc.compression, e.g. From 873b39d81e5544469ca4607f616021080d14e5e0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 4 Jun 2019 13:56:25 -0700 Subject: [PATCH 225/676] Update server_side_auth about the CallCredential --- doc/server_side_auth.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/server_side_auth.md b/doc/server_side_auth.md index d260237928d..e425289faa9 100644 --- a/doc/server_side_auth.md +++ b/doc/server_side_auth.md @@ -2,6 +2,7 @@ Server-side API for Authenticating Clients ========================================== NOTE: This document describes how server-side authentication works in C-core based gRPC implementations only. In gRPC Java and Go, server side authentication is handled differently. +NOTE2: `CallCredentials` class is only valid for secure channels in C-Core. So, for connections under insecure channels, features below might not be avaiable. ## AuthContext From 05e26ff4cfd167d29c30b40ca689879075c9b585 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Jun 2019 11:50:48 -0400 Subject: [PATCH 226/676] introduce --custom_credentials_type to run_interop_tests.py --- tools/run_tests/run_interop_tests.py | 68 ++++++++++++---------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 108f91e8383..0845647ecd6 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -738,6 +738,10 @@ _SERVERS_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] _TRANSPORT_SECURITY_OPTIONS = ['tls', 'alts', 'insecure'] +_CUSTOM_CREDENTIALS_TYPE_OPTIONS = [ + 'tls', 'google_default_credentials', 'compute_engine_channel_creds' +] + DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' @@ -1267,6 +1271,14 @@ argp.add_argument( nargs='?', const=True, help='Which transport security mechanism to use.') +argp.add_argument( + '--custom_credentials_type', + choices=_CUSTOM_CREDENTIALS_TYPE_OPTIONS, + default=_CUSTOM_CREDENTIALS_TYPE_OPTIONS, + nargs='+', + help= + 'Credential types to test in the cloud_to_prod setup. Default is to test with all creds types possible.' +) argp.add_argument( '--skip_compute_engine_creds', default=False, @@ -1436,39 +1448,20 @@ try: for test_case in _TEST_CASES: if not test_case in language.unimplemented_test_cases(): if not test_case in _SKIP_ADVANCED + _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE: - tls_test_job = cloud_to_prod_jobspec( - language, - test_case, - server_host_nickname, - prod_servers[server_host_nickname], - google_default_creds_use_key_file=args. - google_default_creds_use_key_file, - docker_image=docker_images.get(str(language)), - manual_cmd_log=client_manual_cmd_log, - service_account_key_file=args. - service_account_key_file, - transport_security='tls') - jobs.append(tls_test_job) - if str(language) in [ - 'c++', 'go', 'java', 'javaokhttp' - ]: - google_default_creds_test_job = cloud_to_prod_jobspec( - language, - test_case, - server_host_nickname, - prod_servers[server_host_nickname], - google_default_creds_use_key_file=args. - google_default_creds_use_key_file, - docker_image=docker_images.get( - str(language)), - manual_cmd_log=client_manual_cmd_log, - service_account_key_file=args. - service_account_key_file, - transport_security= - 'google_default_credentials') - jobs.append(google_default_creds_test_job) - if str(language) in ['go', 'java', 'javaokhttp']: - compute_engine_channel_creds_test_job = cloud_to_prod_jobspec( + for transport_security in args.custom_credentials_type: + # google_default_credentials not yet supported by all languages + if transport_security == 'google_default_credentials' and str( + language) not in [ + 'c++', 'go', 'java', 'javaokhttp' + ]: + continue + # compute_engine_channel_creds not yet supported by all languages + if transport_security == 'compute_engine_channel_creds' and str( + language) not in [ + 'go', 'java', 'javaokhttp' + ]: + continue + test_job = cloud_to_prod_jobspec( language, test_case, server_host_nickname, @@ -1480,11 +1473,8 @@ try: manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. service_account_key_file, - transport_security= - 'compute_engine_channel_creds') - jobs.append( - compute_engine_channel_creds_test_job) - + transport_security=transport_security) + jobs.append(test_job) if args.http2_interop: for test_case in _HTTP2_TEST_CASES: test_job = cloud_to_prod_jobspec( @@ -1516,6 +1506,8 @@ try: transport_security = 'compute_engine_channel_creds' else: transport_security = 'tls' + if transport_security not in args.custom_credentials_type: + continue test_job = cloud_to_prod_jobspec( language, test_case, From a1538246fdbfb8b0f6efbaf68fbee0e810ee10fa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Jun 2019 12:16:13 -0400 Subject: [PATCH 227/676] only generate TLS-based testcases for interop_matrix --- tools/interop_matrix/create_testcases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/interop_matrix/create_testcases.sh b/tools/interop_matrix/create_testcases.sh index fa33fa4615f..b3e3ee6cd25 100755 --- a/tools/interop_matrix/create_testcases.sh +++ b/tools/interop_matrix/create_testcases.sh @@ -60,7 +60,7 @@ fi echo $client_lang ${GRPC_ROOT}/tools/run_tests/run_interop_tests.py -l $client_lang --use_docker \ - --cloud_to_prod --prod_servers default gateway_v4 --manual_run + --cloud_to_prod --prod_servers default gateway_v4 --manual_run --custom_credentials_type tls trap cleanup EXIT # TODO(adelez): add test auth tests but do not run if not testing on GCE. From 91b4be4da6030d37461e45e1eb028cc71d03e89c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Jun 2019 13:15:51 -0400 Subject: [PATCH 228/676] regenerate master tescases for c++, java and go --- tools/interop_matrix/testcases/cxx__master | 20 +---------- tools/interop_matrix/testcases/go__master | 38 +-------------------- tools/interop_matrix/testcases/java__master | 38 +-------------------- 3 files changed, 3 insertions(+), 93 deletions(-) diff --git a/tools/interop_matrix/testcases/cxx__master b/tools/interop_matrix/testcases/cxx__master index eb43a15df7d..5739d6649e7 100755 --- a/tools/interop_matrix/testcases/cxx__master +++ b/tools/interop_matrix/testcases/cxx__master @@ -1,40 +1,22 @@ #!/bin/bash # DO NOT MODIFY # This file is generated by run_interop_tests.py/create_testcases.sh -echo "Testing ${docker_image:=grpc_interop_cxx:e5d09e32-2654-4e12-9a2e-1f0715768d1a}" +echo "Testing ${docker_image:=grpc_interop_cxx:f5a2f91d-342a-4bc8-a5ca-eb113dd3a8a2}" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "bins/opt/interop_client --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" diff --git a/tools/interop_matrix/testcases/go__master b/tools/interop_matrix/testcases/go__master index ce61e14e3a1..ab83d6beb0a 100755 --- a/tools/interop_matrix/testcases/go__master +++ b/tools/interop_matrix/testcases/go__master @@ -1,58 +1,22 @@ #!/bin/bash # DO NOT MODIFY # This file is generated by run_interop_tests.py/create_testcases.sh -echo "Testing ${docker_image:=grpc_interop_go:27323929-b77f-4b15-9fe5-21403a49fa31}" +echo "Testing ${docker_image:=grpc_interop_go:45617187-1a75-4f2f-b7af-c602d882bbc0}" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" diff --git a/tools/interop_matrix/testcases/java__master b/tools/interop_matrix/testcases/java__master index ac6b9aed5e6..4f576db754f 100755 --- a/tools/interop_matrix/testcases/java__master +++ b/tools/interop_matrix/testcases/java__master @@ -1,58 +1,22 @@ #!/bin/bash # DO NOT MODIFY # This file is generated by run_interop_tests.py/create_testcases.sh -echo "Testing ${docker_image:=grpc_interop_java:45b54245-f0e4-4e80-ad47-03826412871f}" +echo "Testing ${docker_image:=grpc_interop_java:564ef0d0-f4d8-4611-88a9-bb6a99bf68a8}" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --custom_credentials_type=compute_engine_channel_creds" docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=google_default_credentials" -docker run -i --rm=true -w /var/local/git/grpc/../grpc-java --net=host $docker_image bash -c "./run-test-client.sh --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --custom_credentials_type=compute_engine_channel_creds" From e8bece9c71f93828fc65dc856ec5401fc45e3fe9 Mon Sep 17 00:00:00 2001 From: yuangongji <82787816@qq.com> Date: Wed, 5 Jun 2019 09:33:38 +0800 Subject: [PATCH 229/676] some typo errors too. --- include/grpc/grpc_security.h | 2 +- src/csharp/Grpc.Core/ServerCredentials.cs | 2 +- test/cpp/qps/client_async.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index ebdf86b7d50..909cd2e51ca 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -435,7 +435,7 @@ GRPCAPI grpc_server_credentials* grpc_ssl_server_credentials_create( /** Deprecated in favor of grpc_ssl_server_credentials_create_with_options. Same as grpc_ssl_server_credentials_create method except uses grpc_ssl_client_certificate_request_type enum to support more ways to - authenticate client cerificates.*/ + authenticate client certificates.*/ GRPCAPI grpc_server_credentials* grpc_ssl_server_credentials_create_ex( const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index 8e4e44ba504..d0fc600f85a 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -103,7 +103,7 @@ namespace Grpc.Core /// /// Server requests client certificate and enforces that the client presents a /// certificate. - /// The cerificate presented by the client is verified by the gRPC framework. + /// The certificate presented by the client is verified by the gRPC framework. /// (For a successful connection the client needs to present a certificate that /// can be verified against the root certificate configured by the server) /// The client's key certificate pair must be valid for the SSL connection to diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index bad24cf04a2..059dc4f9002 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -479,7 +479,7 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext { next_state_ = State::STREAM_IDLE; stream_->StartCall(ClientRpcContext::tag(this)); if (coalesce_) { - // When the intial metadata is corked, the tag will not come back and we + // When the initial metadata is corked, the tag will not come back and we // need to manually drive the state machine. RunNextState(true, nullptr); } From 206ca33dd5d320c5cc879b4152641a6128cd4022 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 5 Jun 2019 15:19:55 +1200 Subject: [PATCH 230/676] Enable duplex streaming and special status message interop tests --- tools/run_tests/run_interop_tests.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index cc6901bdebe..ab724e5badc 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -210,12 +210,10 @@ class AspNetCoreLanguage: def unimplemented_test_cases(self): return _SKIP_COMPRESSION + \ - _SKIP_SPECIAL_STATUS_MESSAGE + \ - _AUTH_TEST_CASES + \ - ['cancel_after_first_response', 'ping_pong'] + _AUTH_TEST_CASES def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION def __str__(self): return 'aspnetcore' From de0e9d10269752fa38032f02e1a2e0bb73f271bf Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 20 Mar 2019 07:08:05 -0700 Subject: [PATCH 231/676] enable special_status_message interop for C# --- tools/run_tests/run_interop_tests.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 0845647ecd6..f26111fbf2b 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -145,7 +145,6 @@ class CSharpLanguage: def unimplemented_test_cases(self): return _SKIP_SERVER_COMPRESSION + \ _SKIP_DATA_FRAME_PADDING + \ - _SKIP_SPECIAL_STATUS_MESSAGE + \ _SKIP_GOOGLE_DEFAULT_CREDS + \ _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS @@ -178,7 +177,6 @@ class CSharpCoreCLRLanguage: def unimplemented_test_cases(self): return _SKIP_SERVER_COMPRESSION + \ _SKIP_DATA_FRAME_PADDING + \ - _SKIP_SPECIAL_STATUS_MESSAGE + \ _SKIP_GOOGLE_DEFAULT_CREDS + \ _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS From 4686f6d5183100d8507ca3b6abab95b911c45c40 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 20 Mar 2019 07:08:46 -0700 Subject: [PATCH 232/676] enable special_status_message interop for grpc-dotnet server --- 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 f26111fbf2b..e69e501af5f 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -213,7 +213,7 @@ class AspNetCoreLanguage: ['cancel_after_first_response', 'ping_pong'] def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION def __str__(self): return 'aspnetcore' From 877f426d352de8e1f062aa28c2ea4d2039ef96bf Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 10:52:53 -0400 Subject: [PATCH 233/676] add special_status_message testcase to C# interop client --- .../Grpc.IntegrationTesting/InteropClient.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index 47503530820..83b0095f7f0 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -185,6 +185,9 @@ namespace Grpc.IntegrationTesting case "unimplemented_service": RunUnimplementedService(new UnimplementedService.UnimplementedServiceClient(channel)); break; + case "special_status_message": + await RunSpecialStatusMessageAsync(client); + break; case "unimplemented_method": RunUnimplementedMethod(client); break; @@ -567,6 +570,33 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } + private static async Task RunSpecialStatusMessageAsync(TestService.TestServiceClient client) + { + Console.WriteLine("running special_status_message"); + + var echoStatus = new EchoStatus + { + Code = 2, + Message = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n" + }; + + try + { + await client.UnaryCallAsync(new SimpleRequest + { + ResponseStatus = echoStatus + }); + Assert.Fail(); + } + catch (RpcException e) + { + Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode); + Assert.AreEqual(echoStatus.Message, e.Status.Detail); + } + + Console.WriteLine("Passed!"); + } + public static void RunUnimplementedService(UnimplementedService.UnimplementedServiceClient client) { Console.WriteLine("running unimplemented_service"); From a7e3e76aed60244db57975ef2ee1e2209f47e8b3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 16 Apr 2019 09:04:07 -0400 Subject: [PATCH 234/676] use different service_account_key for interop tests --- .../helper_scripts/prepare_build_interop_rc | 5 ++--- tools/internal_ci/linux/grpc_interop_toprod.cfg | 9 +++++++++ .../linux/pull_request/grpc_interop_toprod.cfg | 9 +++++++++ tools/internal_ci/macos/grpc_interop_toprod.cfg | 10 +++++++++- tools/internal_ci/macos/grpc_interop_toprod.sh | 2 +- tools/run_tests/run_interop_tests.py | 3 ++- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_interop_rc index e462a83e522..03105d9a689 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_interop_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_interop_rc @@ -30,7 +30,6 @@ git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node git clone --recursive https://github.com/grpc/grpc-dart ./../grpc-dart git clone --recursive https://github.com/grpc/grpc-dotnet ./../grpc-dotnet -# Download json file. +# Grab the service account key to run interop tests against prod backends. mkdir ~/service_account -gsutil cp gs://grpc-testing-secrets/interop/service_account/GrpcTesting-726eb1347f15.json ~/service_account -export GOOGLE_APPLICATION_CREDENTIALS=~/service_account/GrpcTesting-726eb1347f15.json +cp "${KOKORO_KEYSTORE_DIR}/73836_interop_to_prod_tests_service_account_key" ~/service_account/grpc-testing-ebe7c1ac7381.json || true diff --git a/tools/internal_ci/linux/grpc_interop_toprod.cfg b/tools/internal_ci/linux/grpc_interop_toprod.cfg index de4db81e6ba..377dff771fe 100644 --- a/tools/internal_ci/linux/grpc_interop_toprod.cfg +++ b/tools/internal_ci/linux/grpc_interop_toprod.cfg @@ -28,3 +28,12 @@ env_vars { key: "RUN_TESTS_FLAGS" value: "-l all --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 --use_docker --internal_ci -t -j 8 --bq_result_table interop_results" } + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "interop_to_prod_tests_service_account_key" + } + } +} diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg index 7321effc123..636f979473b 100644 --- a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg @@ -28,3 +28,12 @@ env_vars { key: "RUN_TESTS_FLAGS" value: "-l all --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 --use_docker --internal_ci -t -j 12" } + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "interop_to_prod_tests_service_account_key" + } + } +} diff --git a/tools/internal_ci/macos/grpc_interop_toprod.cfg b/tools/internal_ci/macos/grpc_interop_toprod.cfg index 2cfc8a2d6de..3c11c749e2f 100644 --- a/tools/internal_ci/macos/grpc_interop_toprod.cfg +++ b/tools/internal_ci/macos/grpc_interop_toprod.cfg @@ -17,7 +17,6 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_interop_toprod.sh" gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" -gfile_resources: "/bigstore/grpc-testing-secrets/interop/service_account/GrpcTesting-726eb1347f15.json" timeout_mins: 240 action { define_artifacts { @@ -25,3 +24,12 @@ action { regex: "github/grpc/reports/**" } } + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73836 + keyname: "interop_to_prod_tests_service_account_key" + } + } +} diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index 654da373a26..36e5a2103d9 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -33,7 +33,7 @@ tools/run_tests/run_interop_tests.py -l c++ \ --cloud_to_prod --cloud_to_prod_auth \ --google_default_creds_use_key_file \ --prod_servers default gateway_v4 \ - --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \ + --service_account_key_file="${KOKORO_KEYSTORE_DIR}/73836_interop_to_prod_tests_service_account_key" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" tools/internal_ci/helper_scripts/delete_nonartifacts.sh || true diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 0845647ecd6..c0f153f0106 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -823,9 +823,10 @@ def auth_options(language, if not service_account_key_file: # this file path only works inside docker - service_account_key_file = '/root/service_account/GrpcTesting-726eb1347f15.json' + service_account_key_file = '/root/service_account/grpc-testing-ebe7c1ac7381.json' oauth_scope_arg = '--oauth_scope=https://www.googleapis.com/auth/xapi.zoo' key_file_arg = '--service_account_key_file=%s' % service_account_key_file + # default compute engine credentials associated with the testing VMs in "grpc-testing" cloud project default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: From 2699ee6243a31cea7cb1884e1e9bf31b7b7f74eb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 18:34:10 +0200 Subject: [PATCH 235/676] improve C# readme.md --- src/csharp/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/csharp/README.md b/src/csharp/README.md index c01cae0422d..13c8502af61 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -17,20 +17,20 @@ PREREQUISITES When using gRPC C# under .NET Core you only need to [install .NET Core](https://www.microsoft.com/net/core). In addition to that, you can also use gRPC C# with these runtimes / IDEs -- Windows: .NET Framework 4.5+, Visual Studio 2013, 2015, 2017, Visual Studio Code -- Linux: Mono 4+, Visual Studio Code, MonoDevelop 5.9+ -- Mac OS X: Mono 4+, Visual Studio Code, Xamarin Studio 5.9+ +- Windows: .NET Framework 4.5+, Visual Studio 2013 or newer, Visual Studio Code +- Linux: Mono 4+, Visual Studio Code +- Mac OS X: Mono 4+, Visual Studio Code, Visual Studio for Mac HOW TO USE -------------- **Windows, Linux, Mac OS X** -- Open Visual Studio / MonoDevelop / Xamarin Studio and start a new project/solution (alternatively, you can create a new project from command line with `dotnet` SDK) +- Open Visual Studio and start a new project/solution (alternatively, you can create a new project from command line with `dotnet` SDK) - Add the [Grpc](https://www.nuget.org/packages/Grpc/) NuGet package as a dependency (Project options -> Manage NuGet Packages). -- To be able to generate code from Protocol Buffer (`.proto`) file definitions, add the [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) NuGet package that contains Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin. +- To be able to generate code from Protocol Buffer (`.proto`) file definitions, add the [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) NuGet package which provides [code generation integrated into your build](BUILD-INTEGRATION.md). **Xamarin.Android and Xamarin.iOS (Experimental only)** From f32a49d05f966329b3e97d05082d44329229abfa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 18:34:48 +0200 Subject: [PATCH 236/676] document grpc_csharp_plugin options --- src/csharp/BUILD-INTEGRATION.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/csharp/BUILD-INTEGRATION.md b/src/csharp/BUILD-INTEGRATION.md index 3addc2403c5..400365ab24a 100644 --- a/src/csharp/BUILD-INTEGRATION.md +++ b/src/csharp/BUILD-INTEGRATION.md @@ -355,3 +355,24 @@ Unless explicitly set, will follow `OutputDir` for any given file. * __Access__ Sets generated class access on _both_ generated message and gRPC stub classes. + +`grpc_csharp_plugin` command line options +--------- + +Under the hood, the `Grpc.Tools` build integration invokes the `protoc` and `grpc_csharp_plugin` binaries +to perform code generation. Here is an overview of the available `grpc_csharp_plugin` options: + +| Name | Default | Synopsis | +|---------------- |-----------|----------------------------------------------------------| +| no_client | off | Don't generate the client stub | +| no_server | off | Don't generate the server-side stub | +| internal_access | off | Generate classes with "internal" visibility | +| lite_client | off | Generate client stubs that inherit from "LiteClientBase" | + +Note that the protocol buffer compiler has a special commandline syntax for plugin options. +Example: +``` +protoc --plugin=protoc-gen-grpc=grpc_csharp_plugin --csharp_out=OUT_DIR \ + --grpc_out=OUT_DIR --grpc_opt=lite_client,no_server \ + -I INCLUDE_DIR foo.proto +``` \ No newline at end of file From e466546743b485e1d7c9060f7bffc1ee3f3de8fd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 18:56:24 +0200 Subject: [PATCH 237/676] make reference docs tooling to docfx directory to avoid collision --- src/csharp/{doc => docfx}/.gitignore | 0 src/csharp/{doc => docfx}/README.md | 0 src/csharp/{doc => docfx}/docfx.json | 0 src/csharp/{doc => docfx}/generate_reference_docs.sh | 4 ++-- src/csharp/{doc => docfx}/toc.yml | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename src/csharp/{doc => docfx}/.gitignore (100%) rename src/csharp/{doc => docfx}/README.md (100%) rename src/csharp/{doc => docfx}/docfx.json (100%) rename src/csharp/{doc => docfx}/generate_reference_docs.sh (90%) rename src/csharp/{doc => docfx}/toc.yml (100%) diff --git a/src/csharp/doc/.gitignore b/src/csharp/docfx/.gitignore similarity index 100% rename from src/csharp/doc/.gitignore rename to src/csharp/docfx/.gitignore diff --git a/src/csharp/doc/README.md b/src/csharp/docfx/README.md similarity index 100% rename from src/csharp/doc/README.md rename to src/csharp/docfx/README.md diff --git a/src/csharp/doc/docfx.json b/src/csharp/docfx/docfx.json similarity index 100% rename from src/csharp/doc/docfx.json rename to src/csharp/docfx/docfx.json diff --git a/src/csharp/doc/generate_reference_docs.sh b/src/csharp/docfx/generate_reference_docs.sh similarity index 90% rename from src/csharp/doc/generate_reference_docs.sh rename to src/csharp/docfx/generate_reference_docs.sh index c20d6c30bd3..dbed2bad27f 100755 --- a/src/csharp/doc/generate_reference_docs.sh +++ b/src/csharp/docfx/generate_reference_docs.sh @@ -23,7 +23,7 @@ rm -rf html obj grpc-gh-pages # generate into src/csharp/doc/html directory cd .. docker run --rm -v "$(pwd)":/work -w /work/doc --user "$(id -u):$(id -g)" -it tsgkadot/docker-docfx:latest docfx -cd doc +cd docfx # prepare a clone of "gh-pages" branch where the generated docs are stored GITHUB_USER="${USER}" @@ -35,4 +35,4 @@ git remote add origin "git@github.com:${GITHUB_USER}/grpc.git" rm -r csharp cp -r ../html csharp -echo "Done. Go to src/csharp/doc/grpc-gh-pages git repository and create a pull request to update the generated docs." +echo "Done. Go to src/csharp/docfx/grpc-gh-pages git repository and create a pull request to update the generated docs." diff --git a/src/csharp/doc/toc.yml b/src/csharp/docfx/toc.yml similarity index 100% rename from src/csharp/doc/toc.yml rename to src/csharp/docfx/toc.yml From 76508bd450b13eab03b222e270cd9ad22b573edb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 5 Jun 2019 08:34:30 -0700 Subject: [PATCH 238/676] Change ChannelzRegistry::Get() to return a RefCountedPtr<>. --- src/core/lib/channel/channelz_registry.cc | 118 ++++++++++++-------- src/core/lib/channel/channelz_registry.h | 6 +- src/core/lib/gprpp/ref_counted.h | 5 + test/core/channel/channelz_registry_test.cc | 76 +++++++------ 4 files changed, 120 insertions(+), 85 deletions(-) diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index b6a660b18fd..0c033a14c60 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -117,36 +117,46 @@ void ChannelzRegistry::InternalUnregister(intptr_t uuid) { MaybePerformCompactionLocked(); } -BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) { +RefCountedPtr ChannelzRegistry::InternalGet(intptr_t uuid) { MutexLock lock(&mu_); if (uuid < 1 || uuid > uuid_generator_) { return nullptr; } int idx = FindByUuidLocked(uuid, true); - return idx < 0 ? nullptr : entities_[idx]; + if (idx < 0 || entities_[idx] == nullptr) return nullptr; + // Found node. Return only if its refcount is not zero (i.e., when we + // know that there is no other thread about to destroy it). + if (!entities_[idx]->RefIfNonZero()) return nullptr; + return RefCountedPtr(entities_[idx]); } char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { - MutexLock lock(&mu_); grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - InlinedVector top_level_channels; - bool reached_pagination_limit = false; - int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); - for (size_t i = start_idx; i < entities_.size(); ++i) { - if (entities_[i] != nullptr && - entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && - entities_[i]->uuid() >= start_channel_id) { - // check if we are over pagination limit to determine if we need to set - // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to kPaginationLimit. - if (top_level_channels.size() == kPaginationLimit) { - reached_pagination_limit = true; - break; + InlinedVector, 10> top_level_channels; + RefCountedPtr node_after_pagination_limit; + { + MutexLock lock(&mu_); + const int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); + for (size_t i = start_idx; i < entities_.size(); ++i) { + if (entities_[i] != nullptr && + entities_[i]->type() == + grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && + entities_[i]->uuid() >= start_channel_id && + entities_[i]->RefIfNonZero()) { + // Check if we are over pagination limit to determine if we need to set + // the "end" element. If we don't go through this block, we know that + // when the loop terminates, we have <= to kPaginationLimit. + // Note that because we have already increased this node's + // refcount, we need to decrease it, but we can't unref while + // holding the lock, because this may lead to a deadlock. + if (top_level_channels.size() == kPaginationLimit) { + node_after_pagination_limit.reset(entities_[i]); + break; + } + top_level_channels.emplace_back(entities_[i]); } - top_level_channels.push_back(entities_[i]); } } if (!top_level_channels.empty()) { @@ -159,7 +169,7 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { grpc_json_link_child(array_parent, channel_json, json_iterator); } } - if (!reached_pagination_limit) { + if (node_after_pagination_limit == nullptr) { grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, false); } @@ -169,26 +179,32 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { } char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { - MutexLock lock(&mu_); grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - InlinedVector servers; - bool reached_pagination_limit = false; - int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); - for (size_t i = start_idx; i < entities_.size(); ++i) { - if (entities_[i] != nullptr && - entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kServer && - entities_[i]->uuid() >= start_server_id) { - // check if we are over pagination limit to determine if we need to set - // the "end" element. If we don't go through this block, we know that - // when the loop terminates, we have <= to kPaginationLimit. - if (servers.size() == kPaginationLimit) { - reached_pagination_limit = true; - break; + InlinedVector, 10> servers; + RefCountedPtr node_after_pagination_limit; + { + MutexLock lock(&mu_); + const int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); + for (size_t i = start_idx; i < entities_.size(); ++i) { + if (entities_[i] != nullptr && + entities_[i]->type() == + grpc_core::channelz::BaseNode::EntityType::kServer && + entities_[i]->uuid() >= start_server_id && + entities_[i]->RefIfNonZero()) { + // Check if we are over pagination limit to determine if we need to set + // the "end" element. If we don't go through this block, we know that + // when the loop terminates, we have <= to kPaginationLimit. + // Note that because we have already increased this node's + // refcount, we need to decrease it, but we can't unref while + // holding the lock, because this may lead to a deadlock. + if (servers.size() == kPaginationLimit) { + node_after_pagination_limit.reset(entities_[i]); + break; + } + servers.emplace_back(entities_[i]); } - servers.push_back(entities_[i]); } } if (!servers.empty()) { @@ -201,7 +217,7 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { grpc_json_link_child(array_parent, server_json, json_iterator); } } - if (!reached_pagination_limit) { + if (node_after_pagination_limit == nullptr) { grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, false); } @@ -211,14 +227,20 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { } void ChannelzRegistry::InternalLogAllEntities() { - MutexLock lock(&mu_); - for (size_t i = 0; i < entities_.size(); ++i) { - if (entities_[i] != nullptr) { - char* json = entities_[i]->RenderJsonString(); - gpr_log(GPR_INFO, "%s", json); - gpr_free(json); + InlinedVector, 10> nodes; + { + MutexLock lock(&mu_); + for (size_t i = 0; i < entities_.size(); ++i) { + if (entities_[i] != nullptr && entities_[i]->RefIfNonZero()) { + nodes.emplace_back(entities_[i]); + } } } + for (size_t i = 0; i < nodes.size(); ++i) { + char* json = nodes[i]->RenderJsonString(); + gpr_log(GPR_INFO, "%s", json); + gpr_free(json); + } } } // namespace channelz @@ -234,7 +256,7 @@ char* grpc_channelz_get_servers(intptr_t start_server_id) { } char* grpc_channelz_get_server(intptr_t server_id) { - grpc_core::channelz::BaseNode* server_node = + grpc_core::RefCountedPtr server_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (server_node == nullptr || server_node->type() != @@ -254,7 +276,7 @@ char* grpc_channelz_get_server(intptr_t server_id) { char* grpc_channelz_get_server_sockets(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results) { - grpc_core::channelz::BaseNode* base_node = + grpc_core::RefCountedPtr base_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (base_node == nullptr || base_node->type() != grpc_core::channelz::BaseNode::EntityType::kServer) { @@ -263,12 +285,12 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, // This cast is ok since we have just checked to make sure base_node is // actually a server node grpc_core::channelz::ServerNode* server_node = - static_cast(base_node); + static_cast(base_node.get()); return server_node->RenderServerSockets(start_socket_id, max_results); } char* grpc_channelz_get_channel(intptr_t channel_id) { - grpc_core::channelz::BaseNode* channel_node = + grpc_core::RefCountedPtr channel_node = grpc_core::channelz::ChannelzRegistry::Get(channel_id); if (channel_node == nullptr || (channel_node->type() != @@ -288,7 +310,7 @@ char* grpc_channelz_get_channel(intptr_t channel_id) { } char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { - grpc_core::channelz::BaseNode* subchannel_node = + grpc_core::RefCountedPtr subchannel_node = grpc_core::channelz::ChannelzRegistry::Get(subchannel_id); if (subchannel_node == nullptr || subchannel_node->type() != @@ -306,7 +328,7 @@ char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { } char* grpc_channelz_get_socket(intptr_t socket_id) { - grpc_core::channelz::BaseNode* socket_node = + grpc_core::RefCountedPtr socket_node = grpc_core::channelz::ChannelzRegistry::Get(socket_id); if (socket_node == nullptr || socket_node->type() != diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index 73b330785d2..aa87b64e5b2 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -48,7 +48,9 @@ class ChannelzRegistry { return Default()->InternalRegister(node); } static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); } - static BaseNode* Get(intptr_t uuid) { return Default()->InternalGet(uuid); } + static RefCountedPtr Get(intptr_t uuid) { + return Default()->InternalGet(uuid); + } // Returns the allocated JSON string that represents the proto // GetTopChannelsResponse as per channelz.proto. @@ -86,7 +88,7 @@ class ChannelzRegistry { // if object with uuid has previously been registered as the correct type, // returns the void* associated with that uuid. Else returns nullptr. - BaseNode* InternalGet(intptr_t uuid); + RefCountedPtr InternalGet(intptr_t uuid); char* InternalGetTopChannels(intptr_t start_channel_id); char* InternalGetServers(intptr_t start_server_id); diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 4de50985dcf..392c12a3bd1 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -221,6 +221,11 @@ class RefCounted : public Impl { } } + bool RefIfNonZero() { return refs_.RefIfNonZero(); } + bool RefIfNonZero(const DebugLocation& location, const char* reason) { + return refs_.RefIfNonZero(location, reason); + } + // Not copyable nor movable. RefCounted(const RefCounted&) = delete; RefCounted& operator=(const RefCounted&) = delete; diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index 31841f9f967..030d52fd548 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -62,8 +62,8 @@ class ChannelzRegistryTest : public ::testing::Test { }; TEST_F(ChannelzRegistryTest, UuidStartsAboveZeroTest) { - UniquePtr channelz_channel = - MakeUnique(BaseNode::EntityType::kTopLevelChannel); + RefCountedPtr channelz_channel = + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel); intptr_t uuid = channelz_channel->uuid(); EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if " "reserved according to " @@ -72,11 +72,11 @@ TEST_F(ChannelzRegistryTest, UuidStartsAboveZeroTest) { } TEST_F(ChannelzRegistryTest, UuidsAreIncreasing) { - std::vector> channelz_channels; + std::vector> channelz_channels; channelz_channels.reserve(10); for (int i = 0; i < 10; ++i) { channelz_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); } for (size_t i = 1; i < channelz_channels.size(); ++i) { EXPECT_LT(channelz_channels[i - 1]->uuid(), channelz_channels[i]->uuid()) @@ -85,46 +85,50 @@ TEST_F(ChannelzRegistryTest, UuidsAreIncreasing) { } TEST_F(ChannelzRegistryTest, RegisterGetTest) { - UniquePtr channelz_channel = - MakeUnique(BaseNode::EntityType::kTopLevelChannel); - BaseNode* retrieved = ChannelzRegistry::Get(channelz_channel->uuid()); - EXPECT_EQ(channelz_channel.get(), retrieved); + RefCountedPtr channelz_channel = + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel); + RefCountedPtr retrieved = + ChannelzRegistry::Get(channelz_channel->uuid()); + EXPECT_EQ(channelz_channel, retrieved); } TEST_F(ChannelzRegistryTest, RegisterManyItems) { - std::vector> channelz_channels; + std::vector> channelz_channels; for (int i = 0; i < 100; i++) { channelz_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); - BaseNode* retrieved = ChannelzRegistry::Get(channelz_channels[i]->uuid()); - EXPECT_EQ(channelz_channels[i].get(), retrieved); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); + RefCountedPtr retrieved = + ChannelzRegistry::Get(channelz_channels[i]->uuid()); + EXPECT_EQ(channelz_channels[i], retrieved); } } TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) { - UniquePtr channelz_channel = - MakeUnique(BaseNode::EntityType::kTopLevelChannel); + RefCountedPtr channelz_channel = + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel); // try to pull out a uuid that does not exist. - BaseNode* nonexistant = ChannelzRegistry::Get(channelz_channel->uuid() + 1); + RefCountedPtr nonexistant = + ChannelzRegistry::Get(channelz_channel->uuid() + 1); EXPECT_EQ(nonexistant, nullptr); - BaseNode* retrieved = ChannelzRegistry::Get(channelz_channel->uuid()); - EXPECT_EQ(channelz_channel.get(), retrieved); + RefCountedPtr retrieved = + ChannelzRegistry::Get(channelz_channel->uuid()); + EXPECT_EQ(channelz_channel, retrieved); } TEST_F(ChannelzRegistryTest, TestCompaction) { const int kLoopIterations = 300; // These channels that will stay in the registry for the duration of the test. - std::vector> even_channels; + std::vector> even_channels; even_channels.reserve(kLoopIterations); { // The channels will unregister themselves at the end of the for block. - std::vector> odd_channels; + std::vector> odd_channels; odd_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { even_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); odd_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); } } // without compaction, there would be exactly kLoopIterations empty slots at @@ -137,25 +141,26 @@ TEST_F(ChannelzRegistryTest, TestCompaction) { TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) { const int kLoopIterations = 100; // These channels that will stay in the registry for the duration of the test. - std::vector> even_channels; + std::vector> even_channels; even_channels.reserve(kLoopIterations); std::vector odd_uuids; odd_uuids.reserve(kLoopIterations); { // The channels will unregister themselves at the end of the for block. - std::vector> odd_channels; + std::vector> odd_channels; odd_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { even_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); odd_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); odd_uuids.push_back(odd_channels[i]->uuid()); } } for (int i = 0; i < kLoopIterations; i++) { - BaseNode* retrieved = ChannelzRegistry::Get(even_channels[i]->uuid()); - EXPECT_EQ(even_channels[i].get(), retrieved); + RefCountedPtr retrieved = + ChannelzRegistry::Get(even_channels[i]->uuid()); + EXPECT_EQ(even_channels[i], retrieved); retrieved = ChannelzRegistry::Get(odd_uuids[i]); EXPECT_EQ(retrieved, nullptr); } @@ -164,29 +169,30 @@ TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) { TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) { const int kLoopIterations = 100; // These channels that will stay in the registry for the duration of the test. - std::vector> even_channels; + std::vector> even_channels; even_channels.reserve(kLoopIterations); std::vector odd_uuids; odd_uuids.reserve(kLoopIterations); { // The channels will unregister themselves at the end of the for block. - std::vector> odd_channels; + std::vector> odd_channels; odd_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { even_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); odd_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); odd_uuids.push_back(odd_channels[i]->uuid()); } } - std::vector> more_channels; + std::vector> more_channels; more_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { more_channels.push_back( - MakeUnique(BaseNode::EntityType::kTopLevelChannel)); - BaseNode* retrieved = ChannelzRegistry::Get(more_channels[i]->uuid()); - EXPECT_EQ(more_channels[i].get(), retrieved); + MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); + RefCountedPtr retrieved = + ChannelzRegistry::Get(more_channels[i]->uuid()); + EXPECT_EQ(more_channels[i], retrieved); } } From 226e63dd0c84c378918cb3c91299b7d57887ec3c Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 4 Jun 2019 15:01:25 -0700 Subject: [PATCH 239/676] Move server context implementation to grpc_impl namespace and typedef the ref to it --- .gitignore | 2 + BUILD | 1 + BUILD.gn | 1 + CMakeLists.txt | 5 + Makefile | 5 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/impl/codegen/client_context.h | 6 +- .../impl/codegen/completion_queue_impl.h | 4 +- .../grpcpp/impl/codegen/rpc_service_method.h | 8 +- include/grpcpp/impl/codegen/server_callback.h | 42 +- include/grpcpp/impl/codegen/server_context.h | 355 +---------------- .../grpcpp/impl/codegen/server_context_impl.h | 377 ++++++++++++++++++ .../grpcpp/impl/codegen/server_interceptor.h | 14 +- .../grpcpp/impl/codegen/server_interface.h | 22 +- include/grpcpp/impl/codegen/service_type.h | 11 +- include/grpcpp/opencensus.h | 2 +- include/grpcpp/opencensus_impl.h | 8 +- include/grpcpp/server_impl.h | 6 +- src/compiler/cpp_generator.cc | 2 +- src/cpp/ext/filters/census/grpc_plugin.h | 5 +- src/cpp/server/server_context.cc | 38 +- test/cpp/codegen/compiler_test_golden | 2 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 26 files changed, 491 insertions(+), 431 deletions(-) create mode 100644 include/grpcpp/impl/codegen/server_context_impl.h diff --git a/.gitignore b/.gitignore index bc324b5f826..a8c58277c34 100644 --- a/.gitignore +++ b/.gitignore @@ -144,3 +144,5 @@ bm_*.json !.vscode/launch.json !.vscode/extensions.json +# Clion artifacts +cmake-build-debug/ diff --git a/BUILD b/BUILD index e0827d46cb1..398099774e6 100644 --- a/BUILD +++ b/BUILD @@ -2185,6 +2185,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", diff --git a/BUILD.gn b/BUILD.gn index 258cdc9f873..61982917aca 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1081,6 +1081,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index e9d2168b8de..868de744eaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3334,6 +3334,7 @@ foreach(_hdr include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h include/grpcpp/impl/codegen/server_interface.h include/grpcpp/impl/codegen/service_type.h @@ -3953,6 +3954,7 @@ foreach(_hdr include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h include/grpcpp/impl/codegen/server_interface.h include/grpcpp/impl/codegen/service_type.h @@ -4388,6 +4390,7 @@ foreach(_hdr include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h include/grpcpp/impl/codegen/server_interface.h include/grpcpp/impl/codegen/service_type.h @@ -4587,6 +4590,7 @@ foreach(_hdr include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h include/grpcpp/impl/codegen/server_interface.h include/grpcpp/impl/codegen/service_type.h @@ -4946,6 +4950,7 @@ foreach(_hdr include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h include/grpcpp/impl/codegen/server_context.h + include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h include/grpcpp/impl/codegen/server_interface.h include/grpcpp/impl/codegen/service_type.h diff --git a/Makefile b/Makefile index e56c5ec4e47..3ece4e0cc0c 100644 --- a/Makefile +++ b/Makefile @@ -5691,6 +5691,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ + include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ @@ -6318,6 +6319,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ + include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ @@ -6725,6 +6727,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ + include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ @@ -6895,6 +6898,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ + include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ @@ -7260,6 +7264,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ + include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ diff --git a/build.yaml b/build.yaml index 5c085f18787..6f4dafefd3f 100644 --- a/build.yaml +++ b/build.yaml @@ -1281,6 +1281,7 @@ filegroups: - include/grpcpp/impl/codegen/serialization_traits.h - include/grpcpp/impl/codegen/server_callback.h - include/grpcpp/impl/codegen/server_context.h + - include/grpcpp/impl/codegen/server_context_impl.h - include/grpcpp/impl/codegen/server_interceptor.h - include/grpcpp/impl/codegen/server_interface.h - include/grpcpp/impl/codegen/service_type.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3b463cf7b90..f7df93f213e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -182,6 +182,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/serialization_traits.h', 'include/grpcpp/impl/codegen/server_callback.h', 'include/grpcpp/impl/codegen/server_context.h', + 'include/grpcpp/impl/codegen/server_context_impl.h', 'include/grpcpp/impl/codegen/server_interceptor.h', 'include/grpcpp/impl/codegen/server_interface.h', 'include/grpcpp/impl/codegen/service_type.h', diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 999d8fcbfe7..28eece5deba 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -62,6 +62,7 @@ namespace grpc_impl { class CallCredentials; class Channel; class CompletionQueue; +class ServerContext; } // namespace grpc_impl namespace grpc { @@ -99,7 +100,6 @@ template class ClientAsyncReaderWriter; template class ClientAsyncResponseReader; -class ServerContext; /// Options for \a ClientContext::FromServerContext specifying which traits from /// the \a ServerContext to propagate (copy) from it into a new \a @@ -192,12 +192,12 @@ class ClientContext { /// \return A newly constructed \a ClientContext instance based on \a /// server_context, with traits propagated (copied) according to \a options. static std::unique_ptr FromServerContext( - const ServerContext& server_context, + const ::grpc_impl::ServerContext& server_context, PropagationOptions options = PropagationOptions()); /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with /// a client call. These are made available at the server side by the \a - /// grpc::ServerContext::client_metadata() method. + /// grpc_impl::ServerContext::client_metadata() method. /// /// \warning This method should only be called before invoking the rpc. /// diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index d5c4bb0f201..a4cd1d0abfb 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -46,6 +46,7 @@ namespace grpc_impl { class Channel; class Server; class ServerBuilder; +class ServerContext; } // namespace grpc_impl namespace grpc { @@ -66,7 +67,6 @@ class ServerReaderWriterBody; class ChannelInterface; class ClientContext; -class ServerContext; class ServerInterface; namespace internal { @@ -278,7 +278,7 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { template <::grpc::StatusCode code> friend class ::grpc::internal::ErrorMethodHandler; friend class ::grpc_impl::Server; - friend class ::grpc::ServerContext; + friend class ::grpc_impl::ServerContext; friend class ::grpc::ServerInterface; template friend class ::grpc::internal::BlockingUnaryCallImpl; diff --git a/include/grpcpp/impl/codegen/rpc_service_method.h b/include/grpcpp/impl/codegen/rpc_service_method.h index 21fb2ac2130..0b16feed820 100644 --- a/include/grpcpp/impl/codegen/rpc_service_method.h +++ b/include/grpcpp/impl/codegen/rpc_service_method.h @@ -31,9 +31,11 @@ #include #include -namespace grpc { +namespace grpc_impl { class ServerContext; +} +namespace grpc { namespace internal { /// Base class for running an RPC handler. class MethodHandler { @@ -50,7 +52,7 @@ class MethodHandler { /// \param requester : used only by the callback API. It is a function /// called by the RPC Controller to request another RPC (and also /// to set up the state required to make that request possible) - HandlerParameter(Call* c, ServerContext* context, void* req, + HandlerParameter(Call* c, ::grpc_impl::ServerContext* context, void* req, Status req_status, void* handler_data, std::function requester) : call(c), @@ -61,7 +63,7 @@ class MethodHandler { call_requester(std::move(requester)) {} ~HandlerParameter() {} Call* call; - ServerContext* server_context; + ::grpc_impl::ServerContext* server_context; void* request; Status status; void* internal_data; diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 9254518b605..da08ec963e4 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include @@ -53,7 +53,7 @@ class ServerReactor { virtual void OnCancel() = 0; private: - friend class ::grpc::ServerContext; + friend class ::grpc_impl::ServerContext; template friend class CallbackClientStreamingHandler; template @@ -313,7 +313,7 @@ class ServerBidiReactor : public internal::ServerReactor { /// is a result of the client calling StartCall(). /// /// \param[in] context The context object now associated with this RPC - virtual void OnStarted(ServerContext* context) {} + virtual void OnStarted(::grpc_impl::ServerContext* context) {} /// Notifies the application that an explicit StartSendInitialMetadata /// operation completed. Not used when the sending of initial metadata @@ -372,7 +372,7 @@ class ServerReadReactor : public internal::ServerReactor { /// /// \param[in] context The context object now associated with this RPC /// \param[in] resp The response object to be used by this RPC - virtual void OnStarted(ServerContext* context, Response* resp) {} + virtual void OnStarted(::grpc_impl::ServerContext* context, Response* resp) {} /// The following notifications are exactly like ServerBidiReactor. virtual void OnSendInitialMetadataDone(bool ok) {} @@ -413,7 +413,8 @@ class ServerWriteReactor : public internal::ServerReactor { /// /// \param[in] context The context object now associated with this RPC /// \param[in] req The request object sent by the client - virtual void OnStarted(ServerContext* context, const Request* req) {} + virtual void OnStarted(::grpc_impl::ServerContext* context, + const Request* req) {} /// The following notifications are exactly like ServerBidiReactor. virtual void OnSendInitialMetadataDone(bool ok) {} @@ -437,7 +438,7 @@ class UnimplementedReadReactor : public experimental::ServerReadReactor { public: void OnDone() override { delete this; } - void OnStarted(ServerContext*, Response*) override { + void OnStarted(::grpc_impl::ServerContext*, Response*) override { this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); } }; @@ -447,7 +448,7 @@ class UnimplementedWriteReactor : public experimental::ServerWriteReactor { public: void OnDone() override { delete this; } - void OnStarted(ServerContext*, const Request*) override { + void OnStarted(::grpc_impl::ServerContext*, const Request*) override { this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); } }; @@ -457,7 +458,7 @@ class UnimplementedBidiReactor : public experimental::ServerBidiReactor { public: void OnDone() override { delete this; } - void OnStarted(ServerContext*) override { + void OnStarted(::grpc_impl::ServerContext*) override { this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); } }; @@ -466,7 +467,8 @@ template class CallbackUnaryHandler : public MethodHandler { public: CallbackUnaryHandler( - std::function func) : func_(func) {} @@ -525,8 +527,8 @@ class CallbackUnaryHandler : public MethodHandler { } private: - std::function + std::function func_; experimental::MessageAllocator* allocator_ = nullptr; @@ -597,7 +599,7 @@ class CallbackUnaryHandler : public MethodHandler { friend class CallbackUnaryHandler; ServerCallbackRpcControllerImpl( - ServerContext* ctx, Call* call, + ::grpc_impl::ServerContext* ctx, Call* call, experimental::MessageHolder* allocator_state, std::function call_requester) : ctx_(ctx), @@ -628,7 +630,7 @@ class CallbackUnaryHandler : public MethodHandler { finish_ops_; CallbackWithSuccessTag finish_tag_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; Call call_; experimental::MessageHolder* const allocator_state_; @@ -732,7 +734,8 @@ class CallbackClientStreamingHandler : public MethodHandler { friend class CallbackClientStreamingHandler; ServerCallbackReaderImpl( - ServerContext* ctx, Call* call, std::function call_requester, + ::grpc_impl::ServerContext* ctx, Call* call, + std::function call_requester, experimental::ServerReadReactor* reactor) : ctx_(ctx), call_(*call), @@ -772,7 +775,7 @@ class CallbackClientStreamingHandler : public MethodHandler { CallOpSet> read_ops_; CallbackWithSuccessTag read_tag_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; Call call_; ResponseType resp_; std::function call_requester_; @@ -909,7 +912,7 @@ class CallbackServerStreamingHandler : public MethodHandler { friend class CallbackServerStreamingHandler; ServerCallbackWriterImpl( - ServerContext* ctx, Call* call, const RequestType* req, + ::grpc_impl::ServerContext* ctx, Call* call, const RequestType* req, std::function call_requester, experimental::ServerWriteReactor* reactor) : ctx_(ctx), @@ -950,7 +953,7 @@ class CallbackServerStreamingHandler : public MethodHandler { CallOpSet write_ops_; CallbackWithSuccessTag write_tag_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; Call call_; const RequestType* req_; std::function call_requester_; @@ -1078,7 +1081,8 @@ class CallbackBidiHandler : public MethodHandler { friend class CallbackBidiHandler; ServerCallbackReaderWriterImpl( - ServerContext* ctx, Call* call, std::function call_requester, + ::grpc_impl::ServerContext* ctx, Call* call, + std::function call_requester, experimental::ServerBidiReactor* reactor) : ctx_(ctx), call_(*call), @@ -1124,7 +1128,7 @@ class CallbackBidiHandler : public MethodHandler { CallOpSet> read_ops_; CallbackWithSuccessTag read_tag_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; Call call_; std::function call_requester_; experimental::ServerBidiReactor* reactor_; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index c6903743938..7ae12755a1c 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -19,361 +19,10 @@ #ifndef GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H #define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H -#include -#include -#include +#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_metadata; -struct grpc_call; -struct census_context; - -namespace grpc_impl { - -class CompletionQueue; -class Server; -} // namespace grpc_impl namespace grpc { -class ClientContext; -class GenericServerContext; -class ServerInterface; -template -class ServerAsyncReader; -template -class ServerAsyncWriter; -template -class ServerAsyncResponseWriter; -template -class ServerAsyncReaderWriter; -template -class ServerReader; -template -class ServerWriter; - -namespace internal { -template -class ServerReaderWriterBody; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; -template -class BidiStreamingHandler; -template -class CallbackUnaryHandler; -template -class CallbackClientStreamingHandler; -template -class CallbackServerStreamingHandler; -template -class CallbackBidiHandler; -template -class TemplatedBidiStreamingHandler; -template -class ErrorMethodHandler; -class Call; -class ServerReactor; -} // namespace internal - -class ServerInterface; -namespace testing { -class InteropServerContextInspector; -class ServerContextTestSpouse; -} // namespace testing - -/// A ServerContext allows the person implementing a service handler to: -/// -/// - Add custom initial and trailing metadata key-value pairs that will -/// propagated to the client side. -/// - Control call settings such as compression and authentication. -/// - Access metadata coming from the client. -/// - Get performance metrics (ie, census). -/// -/// Context settings are only relevant to the call handler they are supplied to, -/// that is to say, they aren't sticky across multiple calls. Some of these -/// settings, such as the compression options, can be made persistent at server -/// construction time by specifying the appropriate \a ChannelArguments -/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument. -/// -/// \warning ServerContext instances should \em not be reused across rpcs. -class ServerContext { - public: - ServerContext(); // for async calls - ~ServerContext(); - - /// Return the deadline for the server call. - std::chrono::system_clock::time_point deadline() const { - return Timespec2Timepoint(deadline_); - } - - /// Return a \a gpr_timespec representation of the server call's deadline. - gpr_timespec raw_deadline() const { return deadline_; } - - /// Add the (\a key, \a value) pair to the initial metadata - /// associated with a server call. These are made available at the client side - /// by the \a grpc::ClientContext::GetServerInitialMetadata() method. - /// - /// \warning This method should only be called before sending initial metadata - /// to the client (which can happen explicitly, or implicitly when sending a - /// a response message or status to the client). - /// - /// \param key The metadata key. If \a value is binary data, it must - /// end in "-bin". - /// \param value The metadata value. If its value is binary, the key name - /// must end in "-bin". - /// - /// Metadata must conform to the following format: - /// Custom-Metadata -> Binary-Header / ASCII-Header - /// Binary-Header -> {Header-Name "-bin" } {binary value} - /// ASCII-Header -> Header-Name ASCII-Value - /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . - /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII - void AddInitialMetadata(const grpc::string& key, const grpc::string& value); - - /// Add the (\a key, \a value) pair to the initial metadata - /// associated with a server call. These are made available at the client - /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method. - /// - /// \warning This method should only be called before sending trailing - /// metadata to the client (which happens when the call is finished and a - /// status is sent to the client). - /// - /// \param key The metadata key. If \a value is binary data, - /// it must end in "-bin". - /// \param value The metadata value. If its value is binary, the key name - /// must end in "-bin". - /// - /// Metadata must conform to the following format: - /// Custom-Metadata -> Binary-Header / ASCII-Header - /// Binary-Header -> {Header-Name "-bin" } {binary value} - /// ASCII-Header -> Header-Name ASCII-Value - /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . - /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII - void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); - - /// IsCancelled is always safe to call when using sync or callback API. - /// When using async API, it is only safe to call IsCancelled after - /// the AsyncNotifyWhenDone tag has been delivered. - bool IsCancelled() const; - - /// Cancel the Call from the server. This is a best-effort API and - /// depending on when it is called, the RPC may still appear successful to - /// the client. - /// For example, if TryCancel() is called on a separate thread, it might race - /// with the server handler which might return success to the client before - /// TryCancel() was even started by the thread. - /// - /// It is the caller's responsibility to prevent such races and ensure that if - /// TryCancel() is called, the serverhandler must return Status::CANCELLED. - /// The only exception is that if the serverhandler is already returning an - /// error status code, it is ok to not return Status::CANCELLED even if - /// TryCancel() was called. - /// - /// Note that TryCancel() does not change any of the tags that are pending - /// on the completion queue. All pending tags will still be delivered - /// (though their ok result may reflect the effect of cancellation). - void TryCancel() const; - - /// Return a collection of initial metadata key-value pairs sent from the - /// client. Note that keys may happen more than - /// once (ie, a \a std::multimap is returned). - /// - /// It is safe to use this method after initial metadata has been received, - /// Calls always begin with the client sending initial metadata, so this is - /// safe to access as soon as the call has begun on the server side. - /// - /// \return A multimap of initial metadata key-value pairs from the server. - const std::multimap& client_metadata() - const { - return *client_metadata_.map(); - } - - /// Return the compression algorithm to be used by the server call. - grpc_compression_level compression_level() const { - return compression_level_; - } - - /// Set \a level to be the compression level used for the server call. - /// - /// \param level The compression level used for the server call. - void set_compression_level(grpc_compression_level level) { - compression_level_set_ = true; - compression_level_ = level; - } - - /// Return a bool indicating whether the compression level for this call - /// has been set (either implicitly or through a previous call to - /// \a set_compression_level. - bool compression_level_set() const { return compression_level_set_; } - - /// Return the compression algorithm the server call will request be used. - /// Note that the gRPC runtime may decide to ignore this request, for example, - /// due to resource constraints, or if the server is aware the client doesn't - /// support the requested algorithm. - grpc_compression_algorithm compression_algorithm() const { - return compression_algorithm_; - } - /// Set \a algorithm to be the compression algorithm used for the server call. - /// - /// \param algorithm The compression algorithm used for the server call. - void set_compression_algorithm(grpc_compression_algorithm algorithm); - - /// Set the serialized load reporting costs in \a cost_data for the call. - void SetLoadReportingCosts(const std::vector& cost_data); - - /// Return the authentication context for this server call. - /// - /// \see grpc::AuthContext. - std::shared_ptr auth_context() const { - if (auth_context_.get() == nullptr) { - auth_context_ = CreateAuthContext(call_); - } - return auth_context_; - } - - /// Return the peer uri in a string. - /// WARNING: this value is never authenticated or subject to any security - /// related code. It must not be used for any authentication related - /// functionality. Instead, use auth_context. - grpc::string peer() const; - - /// Get the census context associated with this server call. - const struct census_context* census_context() const; - - /// Async only. Has to be called before the rpc starts. - /// Returns the tag in completion queue when the rpc finishes. - /// IsCancelled() can then be called to check whether the rpc was cancelled. - /// TODO(vjpai): Fix this so that the tag is returned even if the call never - /// starts (https://github.com/grpc/grpc/issues/10136). - void AsyncNotifyWhenDone(void* tag) { - has_notify_when_done_tag_ = true; - async_notify_when_done_tag_ = tag; - } - - /// Should be used for framework-level extensions only. - /// Applications never need to call this method. - grpc_call* c_call() { return call_; } - - private: - friend class ::grpc::testing::InteropServerContextInspector; - friend class ::grpc::testing::ServerContextTestSpouse; - friend class ::grpc::ServerInterface; - friend class ::grpc_impl::Server; - template - friend class ::grpc::ServerAsyncReader; - template - friend class ::grpc::ServerAsyncWriter; - template - friend class ::grpc::ServerAsyncResponseWriter; - template - friend class ::grpc::ServerAsyncReaderWriter; - template - friend class ::grpc::ServerReader; - template - friend class ::grpc::ServerWriter; - template - friend class ::grpc::internal::ServerReaderWriterBody; - template - friend class ::grpc::internal::RpcMethodHandler; - template - friend class ::grpc::internal::ClientStreamingHandler; - template - friend class ::grpc::internal::ServerStreamingHandler; - template - friend class ::grpc::internal::TemplatedBidiStreamingHandler; - template - friend class ::grpc::internal::CallbackUnaryHandler; - template - friend class ::grpc::internal::CallbackClientStreamingHandler; - template - friend class ::grpc::internal::CallbackServerStreamingHandler; - template - friend class ::grpc::internal::CallbackBidiHandler; - template - friend class internal::ErrorMethodHandler; - friend class ::grpc::ClientContext; - friend class ::grpc::GenericServerContext; - - /// Prevent copying. - ServerContext(const ServerContext&); - ServerContext& operator=(const ServerContext&); - - class CompletionOp; - - void BeginCompletionOp(internal::Call* call, - std::function callback, - internal::ServerReactor* reactor); - /// Return the tag queued by BeginCompletionOp() - internal::CompletionQueueTag* GetCompletionOpTag(); - - ServerContext(gpr_timespec deadline, grpc_metadata_array* arr); - - void set_call(grpc_call* call) { call_ = call; } - - void BindDeadlineAndMetadata(gpr_timespec deadline, grpc_metadata_array* arr); - - void Clear(); - - void Setup(gpr_timespec deadline); - - uint32_t initial_metadata_flags() const { return 0; } - - void SetCancelCallback(std::function callback); - void ClearCancelCallback(); - - experimental::ServerRpcInfo* set_server_rpc_info( - const char* method, internal::RpcMethod::RpcType type, - const std::vector< - std::unique_ptr>& - creators) { - if (creators.size() != 0) { - rpc_info_ = new experimental::ServerRpcInfo(this, method, type); - rpc_info_->RegisterInterceptors(creators); - } - return rpc_info_; - } - - CompletionOp* completion_op_; - bool has_notify_when_done_tag_; - void* async_notify_when_done_tag_; - internal::CallbackWithSuccessTag completion_tag_; - - gpr_timespec deadline_; - grpc_call* call_; - ::grpc_impl::CompletionQueue* cq_; - bool sent_initial_metadata_; - mutable std::shared_ptr auth_context_; - mutable internal::MetadataMap client_metadata_; - std::multimap initial_metadata_; - std::multimap trailing_metadata_; - - bool compression_level_set_; - grpc_compression_level compression_level_; - grpc_compression_algorithm compression_algorithm_; - - internal::CallOpSet - pending_ops_; - bool has_pending_ops_; - - experimental::ServerRpcInfo* rpc_info_; -}; - +typedef ::grpc_impl::ServerContext ServerContext; } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H diff --git a/include/grpcpp/impl/codegen/server_context_impl.h b/include/grpcpp/impl/codegen/server_context_impl.h new file mode 100644 index 00000000000..5694aaf64dd --- /dev/null +++ b/include/grpcpp/impl/codegen/server_context_impl.h @@ -0,0 +1,377 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_IMPL_H +#define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_IMPL_H +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_metadata; +struct grpc_call; +struct census_context; + +namespace grpc_impl { + +class CompletionQueue; +class Server; +} // namespace grpc_impl +namespace grpc { +class ClientContext; +class GenericServerContext; +class ServerInterface; +template +class ServerAsyncReader; +template +class ServerAsyncWriter; +template +class ServerAsyncResponseWriter; +template +class ServerAsyncReaderWriter; +template +class ServerReader; +template +class ServerWriter; + +namespace internal { +template +class ServerReaderWriterBody; +template +class RpcMethodHandler; +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class BidiStreamingHandler; +template +class CallbackUnaryHandler; +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; +template +class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; +class Call; +class ServerReactor; +} // namespace internal + +class ServerInterface; +namespace testing { +class InteropServerContextInspector; +class ServerContextTestSpouse; +} // namespace testing +} // namespace grpc + +namespace grpc_impl { +/// A ServerContext allows the person implementing a service handler to: +/// +/// - Add custom initial and trailing metadata key-value pairs that will +/// propagated to the client side. +/// - Control call settings such as compression and authentication. +/// - Access metadata coming from the client. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call handler they are supplied to, +/// that is to say, they aren't sticky across multiple calls. Some of these +/// settings, such as the compression options, can be made persistent at server +/// construction time by specifying the appropriate \a ChannelArguments +/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument. +/// +/// \warning ServerContext instances should \em not be reused across rpcs. +class ServerContext { + public: + ServerContext(); // for async calls + ~ServerContext(); + + /// Return the deadline for the server call. + std::chrono::system_clock::time_point deadline() const { + return ::grpc::Timespec2Timepoint(deadline_); + } + + /// Return a \a gpr_timespec representation of the server call's deadline. + gpr_timespec raw_deadline() const { return deadline_; } + + /// Add the (\a key, \a value) pair to the initial metadata + /// associated with a server call. These are made available at the client side + /// by the \a grpc::ClientContext::GetServerInitialMetadata() method. + /// + /// \warning This method should only be called before sending initial metadata + /// to the client (which can happen explicitly, or implicitly when sending a + /// a response message or status to the client). + /// + /// \param key The metadata key. If \a value is binary data, it must + /// end in "-bin". + /// \param value The metadata value. If its value is binary, the key name + /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII + void AddInitialMetadata(const grpc::string& key, const grpc::string& value); + + /// Add the (\a key, \a value) pair to the initial metadata + /// associated with a server call. These are made available at the client + /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method. + /// + /// \warning This method should only be called before sending trailing + /// metadata to the client (which happens when the call is finished and a + /// status is sent to the client). + /// + /// \param key The metadata key. If \a value is binary data, + /// it must end in "-bin". + /// \param value The metadata value. If its value is binary, the key name + /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII + void AddTrailingMetadata(const grpc::string& key, const grpc::string& value); + + /// IsCancelled is always safe to call when using sync or callback API. + /// When using async API, it is only safe to call IsCancelled after + /// the AsyncNotifyWhenDone tag has been delivered. + bool IsCancelled() const; + + /// Cancel the Call from the server. This is a best-effort API and + /// depending on when it is called, the RPC may still appear successful to + /// the client. + /// For example, if TryCancel() is called on a separate thread, it might race + /// with the server handler which might return success to the client before + /// TryCancel() was even started by the thread. + /// + /// It is the caller's responsibility to prevent such races and ensure that if + /// TryCancel() is called, the serverhandler must return Status::CANCELLED. + /// The only exception is that if the serverhandler is already returning an + /// error status code, it is ok to not return Status::CANCELLED even if + /// TryCancel() was called. + /// + /// Note that TryCancel() does not change any of the tags that are pending + /// on the completion queue. All pending tags will still be delivered + /// (though their ok result may reflect the effect of cancellation). + void TryCancel() const; + + /// Return a collection of initial metadata key-value pairs sent from the + /// client. Note that keys may happen more than + /// once (ie, a \a std::multimap is returned). + /// + /// It is safe to use this method after initial metadata has been received, + /// Calls always begin with the client sending initial metadata, so this is + /// safe to access as soon as the call has begun on the server side. + /// + /// \return A multimap of initial metadata key-value pairs from the server. + const std::multimap& client_metadata() + const { + return *client_metadata_.map(); + } + + /// Return the compression algorithm to be used by the server call. + grpc_compression_level compression_level() const { + return compression_level_; + } + + /// Set \a level to be the compression level used for the server call. + /// + /// \param level The compression level used for the server call. + void set_compression_level(grpc_compression_level level) { + compression_level_set_ = true; + compression_level_ = level; + } + + /// Return a bool indicating whether the compression level for this call + /// has been set (either implicitly or through a previous call to + /// \a set_compression_level. + bool compression_level_set() const { return compression_level_set_; } + + /// Return the compression algorithm the server call will request be used. + /// Note that the gRPC runtime may decide to ignore this request, for example, + /// due to resource constraints, or if the server is aware the client doesn't + /// support the requested algorithm. + grpc_compression_algorithm compression_algorithm() const { + return compression_algorithm_; + } + /// Set \a algorithm to be the compression algorithm used for the server call. + /// + /// \param algorithm The compression algorithm used for the server call. + void set_compression_algorithm(grpc_compression_algorithm algorithm); + + /// Set the serialized load reporting costs in \a cost_data for the call. + void SetLoadReportingCosts(const std::vector& cost_data); + + /// Return the authentication context for this server call. + /// + /// \see grpc::AuthContext. + std::shared_ptr auth_context() const { + if (auth_context_.get() == nullptr) { + auth_context_ = ::grpc::CreateAuthContext(call_); + } + return auth_context_; + } + + /// Return the peer uri in a string. + /// WARNING: this value is never authenticated or subject to any security + /// related code. It must not be used for any authentication related + /// functionality. Instead, use auth_context. + grpc::string peer() const; + + /// Get the census context associated with this server call. + const struct census_context* census_context() const; + + /// Async only. Has to be called before the rpc starts. + /// Returns the tag in completion queue when the rpc finishes. + /// IsCancelled() can then be called to check whether the rpc was cancelled. + /// TODO(vjpai): Fix this so that the tag is returned even if the call never + /// starts (https://github.com/grpc/grpc/issues/10136). + void AsyncNotifyWhenDone(void* tag) { + has_notify_when_done_tag_ = true; + async_notify_when_done_tag_ = tag; + } + + /// Should be used for framework-level extensions only. + /// Applications never need to call this method. + grpc_call* c_call() { return call_; } + + private: + friend class ::grpc::testing::InteropServerContextInspector; + friend class ::grpc::testing::ServerContextTestSpouse; + friend class ::grpc::ServerInterface; + friend class ::grpc_impl::Server; + template + friend class ::grpc::ServerAsyncReader; + template + friend class ::grpc::ServerAsyncWriter; + template + friend class ::grpc::ServerAsyncResponseWriter; + template + friend class ::grpc::ServerAsyncReaderWriter; + template + friend class ::grpc::ServerReader; + template + friend class ::grpc::ServerWriter; + template + friend class ::grpc::internal::ServerReaderWriterBody; + template + friend class ::grpc::internal::RpcMethodHandler; + template + friend class ::grpc::internal::ClientStreamingHandler; + template + friend class ::grpc::internal::ServerStreamingHandler; + template + friend class ::grpc::internal::TemplatedBidiStreamingHandler; + template + friend class ::grpc::internal::CallbackUnaryHandler; + template + friend class ::grpc::internal::CallbackClientStreamingHandler; + template + friend class ::grpc::internal::CallbackServerStreamingHandler; + template + friend class ::grpc::internal::CallbackBidiHandler; + template <::grpc::StatusCode code> + friend class ::grpc::internal::ErrorMethodHandler; + friend class ::grpc::ClientContext; + friend class ::grpc::GenericServerContext; + + /// Prevent copying. + ServerContext(const ServerContext&); + ServerContext& operator=(const ServerContext&); + + class CompletionOp; + + void BeginCompletionOp(::grpc::internal::Call* call, + std::function callback, + ::grpc::internal::ServerReactor* reactor); + /// Return the tag queued by BeginCompletionOp() + ::grpc::internal::CompletionQueueTag* GetCompletionOpTag(); + + ServerContext(gpr_timespec deadline, grpc_metadata_array* arr); + + void set_call(grpc_call* call) { call_ = call; } + + void BindDeadlineAndMetadata(gpr_timespec deadline, grpc_metadata_array* arr); + + void Clear(); + + void Setup(gpr_timespec deadline); + + uint32_t initial_metadata_flags() const { return 0; } + + void SetCancelCallback(std::function callback); + void ClearCancelCallback(); + + ::grpc::experimental::ServerRpcInfo* set_server_rpc_info( + const char* method, ::grpc::internal::RpcMethod::RpcType type, + const std::vector>& creators) { + if (creators.size() != 0) { + rpc_info_ = new ::grpc::experimental::ServerRpcInfo(this, method, type); + rpc_info_->RegisterInterceptors(creators); + } + return rpc_info_; + } + + CompletionOp* completion_op_; + bool has_notify_when_done_tag_; + void* async_notify_when_done_tag_; + ::grpc::internal::CallbackWithSuccessTag completion_tag_; + + gpr_timespec deadline_; + grpc_call* call_; + ::grpc_impl::CompletionQueue* cq_; + bool sent_initial_metadata_; + mutable std::shared_ptr auth_context_; + mutable ::grpc::internal::MetadataMap client_metadata_; + std::multimap initial_metadata_; + std::multimap trailing_metadata_; + + bool compression_level_set_; + grpc_compression_level compression_level_; + grpc_compression_algorithm compression_algorithm_; + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage> + pending_ops_; + bool has_pending_ops_; + + ::grpc::experimental::ServerRpcInfo* rpc_info_; +}; +} // namespace grpc_impl +#endif // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_IMPL_H diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 8875a28bf32..28fdc27ec68 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -26,9 +26,11 @@ #include #include -namespace grpc { - +namespace grpc_impl { class ServerContext; +} + +namespace grpc { namespace internal { class InterceptorBatchMethodsImpl; @@ -78,7 +80,7 @@ class ServerRpcInfo { /// Return a pointer to the underlying ServerContext structure associated /// with the RPC to support features that apply to it - grpc::ServerContext* server_context() { return ctx_; } + grpc_impl::ServerContext* server_context() { return ctx_; } private: static_assert(Type::UNARY == @@ -94,7 +96,7 @@ class ServerRpcInfo { static_cast(internal::RpcMethod::BIDI_STREAMING), "violated expectation about Type enum"); - ServerRpcInfo(grpc::ServerContext* ctx, const char* method, + ServerRpcInfo(grpc_impl::ServerContext* ctx, const char* method, internal::RpcMethod::RpcType type) : ctx_(ctx), method_(method), type_(static_cast(type)) { ref_.store(1); @@ -127,14 +129,14 @@ class ServerRpcInfo { } } - grpc::ServerContext* ctx_ = nullptr; + grpc_impl::ServerContext* ctx_ = nullptr; const char* method_ = nullptr; const Type type_; std::atomic_int ref_; std::vector> interceptors_; friend class internal::InterceptorBatchMethodsImpl; - friend class grpc::ServerContext; + friend class grpc_impl::ServerContext; }; } // namespace experimental diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index d8d49344965..9600e5f053d 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -34,12 +34,12 @@ class Channel; class CompletionQueue; class ServerCompletionQueue; class ServerCredentials; +class ServerContext; } // namespace grpc_impl namespace grpc { class AsyncGenericService; class GenericServerContext; -class ServerContext; class Service; extern CoreCodegenInterface* g_core_codegen_interface; @@ -176,7 +176,8 @@ class ServerInterface : public internal::CallHook { class BaseAsyncRequest : public internal::CompletionQueueTag { public: - BaseAsyncRequest(ServerInterface* server, ServerContext* context, + BaseAsyncRequest(ServerInterface* server, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, @@ -190,7 +191,7 @@ class ServerInterface : public internal::CallHook { protected: ServerInterface* const server_; - ServerContext* const context_; + ::grpc_impl::ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; ::grpc_impl::CompletionQueue* const call_cq_; ::grpc_impl::ServerCompletionQueue* const notification_cq_; @@ -205,7 +206,8 @@ class ServerInterface : public internal::CallHook { /// RegisteredAsyncRequest is not part of the C++ API class RegisteredAsyncRequest : public BaseAsyncRequest { public: - RegisteredAsyncRequest(ServerInterface* server, ServerContext* context, + RegisteredAsyncRequest(ServerInterface* server, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, @@ -234,7 +236,8 @@ class ServerInterface : public internal::CallHook { class NoPayloadAsyncRequest final : public RegisteredAsyncRequest { public: NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method, - ServerInterface* server, ServerContext* context, + ServerInterface* server, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, @@ -252,7 +255,8 @@ class ServerInterface : public internal::CallHook { class PayloadAsyncRequest final : public RegisteredAsyncRequest { public: PayloadAsyncRequest(internal::RpcServiceMethod* registered_method, - ServerInterface* server, ServerContext* context, + ServerInterface* server, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, @@ -309,7 +313,7 @@ class ServerInterface : public internal::CallHook { private: internal::RpcServiceMethod* const registered_method_; ServerInterface* const server_; - ServerContext* const context_; + ::grpc_impl::ServerContext* const context_; internal::ServerAsyncStreamingInterface* const stream_; ::grpc_impl::CompletionQueue* const call_cq_; @@ -335,7 +339,7 @@ class ServerInterface : public internal::CallHook { template void RequestAsyncCall(internal::RpcServiceMethod* method, - ServerContext* context, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, @@ -346,7 +350,7 @@ class ServerInterface : public internal::CallHook { } void RequestAsyncCall(internal::RpcServiceMethod* method, - ServerContext* context, + ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, ::grpc_impl::CompletionQueue* call_cq, ::grpc_impl::ServerCompletionQueue* notification_cq, diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index f1d1272dc20..4109ee1b504 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -30,11 +30,11 @@ namespace grpc_impl { class Server; class CompletionQueue; +class ServerContext; } // namespace grpc_impl namespace grpc { class ServerInterface; -class ServerContext; namespace internal { class Call; @@ -146,7 +146,8 @@ class Service { experimental_type experimental() { return experimental_type(this); } template - void RequestAsyncUnary(int index, ServerContext* context, Message* request, + void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context, + Message* request, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { @@ -158,7 +159,7 @@ class Service { notification_cq, tag, request); } void RequestAsyncClientStreaming( - int index, ServerContext* context, + int index, ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); @@ -167,7 +168,7 @@ class Service { } template void RequestAsyncServerStreaming( - int index, ServerContext* context, Message* request, + int index, ::grpc_impl::ServerContext* context, Message* request, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); @@ -175,7 +176,7 @@ class Service { notification_cq, tag, request); } void RequestAsyncBidiStreaming( - int index, ServerContext* context, + int index, ::grpc_impl::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 14c6add1d9e..39bac6bc28c 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -30,7 +30,7 @@ static inline void RegisterOpenCensusViewsForExport() { ::grpc_impl::RegisterOpenCensusViewsForExport(); } static inline ::opencensus::trace::Span GetSpanFromServerContext( - ServerContext* context) { + ::grpc_impl::ServerContext* context) { return ::grpc_impl::GetSpanFromServerContext(context); } diff --git a/include/grpcpp/opencensus_impl.h b/include/grpcpp/opencensus_impl.h index 631d2b861fd..dbcb7c9caeb 100644 --- a/include/grpcpp/opencensus_impl.h +++ b/include/grpcpp/opencensus_impl.h @@ -21,11 +21,8 @@ #include "opencensus/trace/span.h" -namespace grpc { - -class ServerContext; -} namespace grpc_impl { +class ServerContext; // These symbols in this file will not be included in the binary unless // grpc_opencensus_plugin build target was added as a dependency. At the moment // it is only setup to be built with Bazel. @@ -43,8 +40,7 @@ void RegisterOpenCensusPlugin(); void RegisterOpenCensusViewsForExport(); // Returns the tracing Span for the current RPC. -::opencensus::trace::Span GetSpanFromServerContext( - grpc::ServerContext* context); +::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); } // namespace grpc_impl diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 59a780276e0..90019e25032 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -44,7 +44,6 @@ struct grpc_server; namespace grpc { class AsyncGenericService; -class ServerContext; namespace internal { class ExternalConnectionAcceptorImpl; @@ -54,6 +53,7 @@ class ExternalConnectionAcceptorImpl; namespace grpc_impl { class HealthCheckServiceInterface; +class ServerContext; class ServerInitializer; /// Represents a gRPC server. @@ -82,9 +82,9 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// Called before server is created. virtual void UpdateArguments(grpc::ChannelArguments* args) {} /// Called before application callback for each synchronous server request - virtual void PreSynchronousRequest(grpc::ServerContext* context) = 0; + virtual void PreSynchronousRequest(grpc_impl::ServerContext* context) = 0; /// Called after application callback for each synchronous server request - virtual void PostSynchronousRequest(grpc::ServerContext* context) = 0; + virtual void PostSynchronousRequest(grpc_impl::ServerContext* context) = 0; /// Called before server is started. virtual void PreServerStart(Server* server) {} /// Called after a server port is added. diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index bcc849035c6..23e3bd50eff 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -157,13 +157,13 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, printer->Print(vars, "namespace grpc_impl {\n"); printer->Print(vars, "class CompletionQueue;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); + printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc_impl\n\n"); printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "namespace experimental {\n"); printer->Print(vars, "template \n"); printer->Print(vars, "class MessageAllocator;\n"); printer->Print(vars, "} // namespace experimental\n"); - printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); vars["message_header_ext"] = params.message_header_extension.empty() diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 993faae0a94..13176759e37 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -25,8 +25,11 @@ #include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" -namespace grpc { +namespace grpc_impl { class ServerContext; +} + +namespace grpc { // The tag keys set when recording RPC stats. ::opencensus::stats::TagKey ClientMethodTagKey(); diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index eced89d1a79..ba834237ae9 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -16,7 +16,7 @@ * */ -#include +#include #include #include @@ -28,23 +28,25 @@ #include #include #include -#include #include +#include #include #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/surface/call.h" -namespace grpc { +namespace grpc_impl { // CompletionOp -class ServerContext::CompletionOp final : public internal::CallOpSetInterface { +class ServerContext::CompletionOp final + : public ::grpc::internal::CallOpSetInterface { public: // initial refs: one in the server context, one in the cq // must ref the call before calling constructor and after deleting this - CompletionOp(internal::Call* call, internal::ServerReactor* reactor) + CompletionOp(::grpc::internal::Call* call, + ::grpc::internal::ServerReactor* reactor) : call_(*call), reactor_(reactor), has_tag_(false), @@ -67,7 +69,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } } - void FillOps(internal::Call* call) override; + void FillOps(::grpc::internal::Call* call) override; // This should always be arena allocated in the call, so override delete. // But this class is not trivially destructible, so must actually call delete @@ -149,8 +151,8 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { return finalized_ ? (cancelled_ != 0) : false; } - internal::Call call_; - internal::ServerReactor* const reactor_; + ::grpc::internal::Call call_; + ::grpc::internal::ServerReactor* const reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; @@ -160,7 +162,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { int cancelled_; // This is an int (not bool) because it is passed to core std::function cancel_callback_; bool done_intercepting_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; + ::grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; }; void ServerContext::CompletionOp::Unref() { @@ -171,7 +173,7 @@ void ServerContext::CompletionOp::Unref() { } } -void ServerContext::CompletionOp::FillOps(internal::Call* call) { +void ServerContext::CompletionOp::FillOps(::grpc::internal::Call* call) { grpc_op ops; ops.op = GRPC_OP_RECV_CLOSE_ON_SERVER; ops.data.recv_close_on_server.cancelled = &cancelled_; @@ -227,7 +229,7 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { } /* Add interception point and run through interceptors */ interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_CLOSE); + ::grpc::experimental::InterceptionHookPoints::POST_RECV_CLOSE); if (interceptor_methods_.RunInterceptors()) { /* No interceptors were run */ if (has_tag_) { @@ -292,9 +294,9 @@ void ServerContext::Clear() { } } -void ServerContext::BeginCompletionOp(internal::Call* call, - std::function callback, - internal::ServerReactor* reactor) { +void ServerContext::BeginCompletionOp( + ::grpc::internal::Call* call, std::function callback, + ::grpc::internal::ServerReactor* reactor) { GPR_ASSERT(!completion_op_); if (rpc_info_) { rpc_info_->Ref(); @@ -313,8 +315,8 @@ void ServerContext::BeginCompletionOp(internal::Call* call, call->PerformOps(completion_op_); } -internal::CompletionQueueTag* ServerContext::GetCompletionOpTag() { - return static_cast(completion_op_); +::grpc::internal::CompletionQueueTag* ServerContext::GetCompletionOpTag() { + return static_cast<::grpc::internal::CompletionQueueTag*>(completion_op_); } void ServerContext::AddInitialMetadata(const grpc::string& key, @@ -328,7 +330,7 @@ void ServerContext::AddTrailingMetadata(const grpc::string& key, } void ServerContext::TryCancel() const { - internal::CancelInterceptorBatchMethods cancel_methods; + ::grpc::internal::CancelInterceptorBatchMethods cancel_methods; if (rpc_info_) { for (size_t i = 0; i < rpc_info_->interceptors_.size(); i++) { rpc_info_->RunInterceptor(&cancel_methods, i); @@ -398,4 +400,4 @@ void ServerContext::SetLoadReportingCosts( } } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 761c3ac6106..64ab123123b 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -43,6 +43,7 @@ namespace grpc_impl { class CompletionQueue; class ServerCompletionQueue; +class ServerContext; } // namespace grpc_impl namespace grpc { @@ -50,7 +51,6 @@ namespace experimental { template class MessageAllocator; } // namespace experimental -class ServerContext; } // namespace grpc namespace grpc { diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 913d7be993b..859bfdd9d16 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -982,6 +982,7 @@ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ +include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8b664d8ac01..db5ff65a7e9 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -984,6 +984,7 @@ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ include/grpcpp/impl/codegen/server_context.h \ +include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ include/grpcpp/impl/codegen/server_interface.h \ include/grpcpp/impl/codegen/service_type.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a479a00509a..119319758f3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10151,6 +10151,7 @@ "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", @@ -10229,6 +10230,7 @@ "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", From a64ddff19c4ca8b5c2c9ae1aa41b70830a20eaed Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 14:16:51 -0400 Subject: [PATCH 240/676] hijack bazel invocations in grpc workspace --- tools/{bazel.sh => bazel} | 26 +++++++++++++++----------- tools/remote_build/README.md | 11 +++-------- 2 files changed, 18 insertions(+), 19 deletions(-) rename tools/{bazel.sh => bazel} (65%) diff --git a/tools/bazel.sh b/tools/bazel similarity index 65% rename from tools/bazel.sh rename to tools/bazel index 37fd2a242bf..15c78dd0ffa 100755 --- a/tools/bazel.sh +++ b/tools/bazel @@ -19,17 +19,21 @@ # supported version, and then calling it. This way, we can make sure # that running bazel will always get meaningful results, at least # until Bazel 1.0 is released. +# NOTE: This script relies on bazel's feature where //tools/bazel +# script can be used to hijack "bazel" invocations in given workspace. set -e VERSION=0.24.1 -CWD=`pwd` +echo "INFO: Running bazel wrapper (see //tools/bazel for details), bazel version $VERSION will be used instead of system-wide bazel installation." + +CWD=$(pwd) BASEURL=https://github.com/bazelbuild/bazel/releases/download/ -cd `dirname $0` -TOOLDIR=`pwd` +cd "$(dirname "$0")" +TOOLDIR=$(pwd) -case `uname -sm` in +case $(uname -sm) in "Linux x86_64") suffix=linux-x86_64 ;; @@ -37,17 +41,17 @@ case `uname -sm` in suffix=darwin-x86_64 ;; *) - echo "Unsupported architecture: `uname -sm`" + echo "Unsupported architecture: $(uname -sm)" exit 1 ;; esac -filename=bazel-$VERSION-$suffix +filename="bazel-$VERSION-$suffix" -if [ ! -x $filename ] ; then - curl -L $BASEURL/$VERSION/$filename > $filename - chmod a+x $filename +if [ ! -x "$filename" ] ; then + curl -L "$BASEURL/$VERSION/$filename" > "$filename" + chmod a+x "$filename" fi -cd $CWD -$TOOLDIR/$filename $@ +cd "$CWD" +"$TOOLDIR/$filename" $@ diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index 4cc3c7a0ea1..2cd5f03daf1 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -17,27 +17,22 @@ and tests run by Kokoro CI. ## Running remote build manually from dev workstation -*At the time being, tools/bazel.sh is used instead of invoking "bazel" directly -to overcome the bazel versioning problem (our BUILD files currently only work with -a specific window of bazel version and bazel.sh wrapper makes sure that version -is used).* - Run from repository root (opt, dbg): ``` # manual run of bazel tests remotely on Foundry -tools/bazel.sh --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/... +bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/... ``` Sanitizer runs (asan, msan, tsan, ubsan): ``` # manual run of bazel tests remotely on Foundry with given sanitizer -tools/bazel.sh --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... +bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... ``` Run on Windows MSVC: ``` # RBE manual run only for c-core (must be run on a Windows host machine) -tools/bazel.sh --bazelrc=tools/remote_build/windows.bazelrc build :all [--credentials_json=(path to service account credentials)] +bazel --bazelrc=tools/remote_build/windows.bazelrc build :all [--credentials_json=(path to service account credentials)] ``` Available command line options can be found in From ed7e8c53e0a4b3a10b65919e059999e00c12a0bb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 14:21:51 -0400 Subject: [PATCH 241/676] update scripts --- templates/tools/dockerfile/bazel.include | 2 +- tools/dockerfile/test/bazel/Dockerfile | 2 +- tools/dockerfile/test/sanity/Dockerfile | 2 +- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 4 ++-- tools/internal_ci/windows/bazel_rbe.bat | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index 3744dacc281..b46845e218d 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -1,7 +1,7 @@ #======================== # Bazel installation -# Must be in sync with tools/bazel.sh +# Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 RUN apt-get update && apt-get install -y wget && apt-get clean diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index b9fc409d939..0e958542f9a 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -51,7 +51,7 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #======================== # Bazel installation -# Must be in sync with tools/bazel.sh +# Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 RUN apt-get update && apt-get install -y wget && apt-get clean diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index 4ef4a0a9454..18aa89d8bf9 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -97,7 +97,7 @@ ENV CLANG_TIDY=clang-tidy #======================== # Bazel installation -# Must be in sync with tools/bazel.sh +# Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 RUN apt-get update && apt-get install -y wget && apt-get clean diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index bcde79ecd8e..5a358acc09d 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -21,7 +21,7 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc # make sure bazel is available -tools/bazel.sh version +tools/bazel version # to get "bazel" link for kokoro build, we need to generate # invocation UUID, set a flag for bazel to use it @@ -29,7 +29,7 @@ tools/bazel.sh version BAZEL_INVOCATION_ID="$(uuidgen)" echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids" -tools/bazel.sh \ +tools/bazel \ --bazelrc=tools/remote_build/kokoro.bazelrc \ test \ --invocation_id="${BAZEL_INVOCATION_ID}" \ diff --git a/tools/internal_ci/windows/bazel_rbe.bat b/tools/internal_ci/windows/bazel_rbe.bat index 30c66896edf..8abab687ed2 100644 --- a/tools/internal_ci/windows/bazel_rbe.bat +++ b/tools/internal_ci/windows/bazel_rbe.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem TODO(jtattermusch): make this generate less output -@rem TODO(jtattermusch): use tools/bazel.sh script to keep the versions in sync +@rem TODO(jtattermusch): use tools/bazel script to keep the versions in sync choco install bazel -y --version 0.24.1 --limit-output cd github/grpc From bc9d2f6b19b4a46b3829181e0beab19fc6cb355a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Jun 2019 12:54:56 -0700 Subject: [PATCH 242/676] clang-format --- src/objective-c/GRPCClient/GRPCCall.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5a3440f84ed..e97ed6e3a9e 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -717,8 +717,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; // it is ok to set nil because headers are only received once strongSelf.responseHeaders = nil; // copy the header so that the GRPCOpRecvMetadata object may be dealloc'ed - NSDictionary *copiedHeaders = [[NSDictionary alloc] initWithDictionary:headers - copyItems:YES]; + NSDictionary *copiedHeaders = + [[NSDictionary alloc] initWithDictionary:headers copyItems:YES]; strongSelf.responseHeaders = copiedHeaders; strongSelf->_pendingCoreRead = NO; [strongSelf maybeStartNextRead]; From 43fa11e4184814b9be5b3289bc36d3d2d321b132 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 16:32:39 -0700 Subject: [PATCH 243/676] Unpin Cython from 0.28.3 --- requirements.bazel.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index e97843794e4..e2618c950f3 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -1,6 +1,6 @@ # GRPC Python setup requirements coverage>=4.0 -cython==0.28.3 +cython>=0.28.3 enum34>=1.0.4 protobuf>=3.5.0.post1 six>=1.10 diff --git a/requirements.txt b/requirements.txt index 6c978246214..f583fc94eb4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ # GRPC Python setup requirements coverage>=4.0 -cython==0.28.3 +cython>=0.28.3 enum34>=1.0.4 protobuf>=3.5.0.post1 six>=1.10 From f13727dfd110b7e1c95d24acf607d08ca44c4a35 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 16:45:41 -0400 Subject: [PATCH 244/676] add option to disable bazel wrapper --- tools/bazel | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/bazel b/tools/bazel index 15c78dd0ffa..bacfeaddfd2 100755 --- a/tools/bazel +++ b/tools/bazel @@ -24,13 +24,20 @@ set -e +# First of all, if DISABLE_BAZEL_WRAPPER is set, just use BAZEL_REAL as set by +# https://github.com/bazelbuild/bazel/blob/master/scripts/packages/bazel.sh +# that originally invoked this script. +if [ "${BAZEL_REAL}" != "" ] && [ "${DISABLE_BAZEL_WRAPPER}" != "" ] +then + exec -a "$0" "${BAZEL_REAL}" "$@" +fi + VERSION=0.24.1 echo "INFO: Running bazel wrapper (see //tools/bazel for details), bazel version $VERSION will be used instead of system-wide bazel installation." -CWD=$(pwd) BASEURL=https://github.com/bazelbuild/bazel/releases/download/ -cd "$(dirname "$0")" +pushd "$(dirname "$0")" >/dev/null TOOLDIR=$(pwd) case $(uname -sm) in @@ -53,5 +60,5 @@ if [ ! -x "$filename" ] ; then chmod a+x "$filename" fi -cd "$CWD" -"$TOOLDIR/$filename" $@ +popd >/dev/null +exec "$TOOLDIR/$filename" "$@" From e66fb82495da076607eb27cc940714748d870762 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 16:53:12 -0400 Subject: [PATCH 245/676] disable bazel wrapper inside docker containers --- templates/tools/dockerfile/bazel.include | 3 +++ tools/dockerfile/test/bazel/Dockerfile | 3 +++ tools/dockerfile/test/sanity/Dockerfile | 3 +++ 3 files changed, 9 insertions(+) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index b46845e218d..272936007da 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -4,6 +4,9 @@ # Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 +# The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. +ENV DISABLE_BAZEL_WRAPPER 1 + RUN apt-get update && apt-get install -y wget && apt-get clean RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && ${'\\'} bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && ${'\\'} diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 0e958542f9a..df7a7a2f32a 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -54,6 +54,9 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 +# The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. +ENV DISABLE_BAZEL_WRAPPER 1 + RUN apt-get update && apt-get install -y wget && apt-get clean RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && \ bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \ diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index 18aa89d8bf9..9a080d0efb2 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -100,6 +100,9 @@ ENV CLANG_TIDY=clang-tidy # Must be in sync with tools/bazel ENV BAZEL_VERSION 0.24.1 +# The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. +ENV DISABLE_BAZEL_WRAPPER 1 + RUN apt-get update && apt-get install -y wget && apt-get clean RUN wget "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh" && \ bash ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh && \ From b6c89f36cbc2e8effd20d6c22187e226ea984705 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 5 Jun 2019 14:14:08 -0700 Subject: [PATCH 246/676] Change locality name to a class --- .../client_channel/lb_policy/xds/xds.cc | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index b198e0e8637..041c1e46231 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -117,7 +117,9 @@ TraceFlag grpc_lb_xds_trace(false, "xds"); namespace { constexpr char kXds[] = "xds_experimental"; -constexpr char kDefaultLocalityName[] = "xds_default_locality"; +constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region"; +constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone"; +constexpr char kDefaultLocalitySubzone[] = "xds_default_locality_subzone"; constexpr uint32_t kDefaultLocalityWeight = 3; class ParsedXdsConfig : public LoadBalancingPolicy::Config { @@ -352,6 +354,37 @@ class XdsLb : public LoadBalancingPolicy { LoadBalancingPolicy* child_ = nullptr; }; + class LocalityName : public RefCounted { + public: + struct Less { + bool operator()(const RefCountedPtr& lhs, + const RefCountedPtr& rhs) { + int cmp_result = strcmp(lhs->region_.get(), rhs->region_.get()); + if (cmp_result != 0) return cmp_result < 0; + cmp_result = strcmp(lhs->zone_.get(), rhs->zone_.get()); + if (cmp_result != 0) return cmp_result < 0; + return strcmp(lhs->subzone_.get(), rhs->subzone_.get()) < 0; + } + }; + + LocalityName(UniquePtr region, UniquePtr zone, + UniquePtr subzone) + : region_(std::move(region)), + zone_(std::move(zone)), + subzone_(std::move(subzone)) {} + + bool operator==(const LocalityName& other) const { + return strcmp(region_.get(), other.region_.get()) == 0 && + strcmp(zone_.get(), other.zone_.get()) == 0 && + strcmp(subzone_.get(), other.subzone_.get()) == 0; + } + + private: + UniquePtr region_; + UniquePtr zone_; + UniquePtr subzone_; + }; + class LocalityMap { public: class LocalityEntry : public InternallyRefCounted { @@ -418,19 +451,18 @@ class XdsLb : public LoadBalancingPolicy { private: void PruneLocalities(const LocalityList& locality_list); - Map, OrphanablePtr, StringLess> map_; + Map, OrphanablePtr, + LocalityName::Less> + map_; // Lock held while filling child refs for all localities // inside the map Mutex child_refs_mu_; }; struct LocalityServerlistEntry { - ~LocalityServerlistEntry() { - gpr_free(locality_name); - xds_grpclb_destroy_serverlist(serverlist); - } + ~LocalityServerlistEntry() { xds_grpclb_destroy_serverlist(serverlist); } - char* locality_name; + RefCountedPtr locality_name; uint32_t locality_weight; // The deserialized response from the balancer. May be nullptr until one // such response has arrived. @@ -1199,7 +1231,10 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xdslb_policy->locality_serverlist_.emplace_back( MakeUnique()); xdslb_policy->locality_serverlist_[0]->locality_name = - static_cast(gpr_strdup(kDefaultLocalityName)); + MakeRefCounted( + UniquePtr(gpr_strdup(kDefaultLocalityRegion)), + UniquePtr(gpr_strdup(kDefaultLocalityZone)), + UniquePtr(gpr_strdup(kDefaultLocalitySubzone))); xdslb_policy->locality_serverlist_[0]->locality_weight = kDefaultLocalityWeight; } @@ -1728,8 +1763,9 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { for (auto iter = map_.begin(); iter != map_.end();) { bool found = false; for (size_t i = 0; i < locality_list.size(); i++) { - if (!gpr_stricmp(locality_list[i]->locality_name, iter->first.get())) { + if (*locality_list[i]->locality_name == *iter->first) { found = true; + break; } } if (!found) { // Remove entries not present in the locality list @@ -1746,14 +1782,14 @@ void XdsLb::LocalityMap::UpdateLocked( const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { - UniquePtr locality_name( - gpr_strdup(locality_serverlist[i]->locality_name)); - auto iter = map_.find(locality_name); + auto iter = map_.find(locality_serverlist[i]->locality_name); if (iter == map_.end()) { OrphanablePtr new_entry = MakeOrphanable( parent->Ref(), locality_serverlist[i]->locality_weight); MutexLock lock(&child_refs_mu_); - iter = map_.emplace(std::move(locality_name), std::move(new_entry)).first; + iter = map_.emplace(locality_serverlist[i]->locality_name, + std::move(new_entry)) + .first; } // Don't create new child policies if not directed to xds_grpclb_serverlist* serverlist = From e360dd4f76a9e04c1df5e695ec4804b1884dc05b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 5 Jun 2019 23:54:59 +0200 Subject: [PATCH 247/676] Upgrading to bazel 0.26. --- bazel/grpc_deps.bzl | 12 ++++++------ tools/bazel.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index db24c7645b0..4182a7157a0 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -178,9 +178,9 @@ def grpc_deps(): if "com_google_absl" not in native.existing_rules(): http_archive( name = "com_google_absl", - sha256 = "5fe2a3a8f8378e81d4d3db6541f48030e04233ccd2d6c7e9d981ed577b314ae8", - strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45", - url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz", + sha256 = "7ddf863ddced6fa5bf7304103f9c7aa619c20a2fcf84475512c8d3834b9d14fa", + strip_prefix = "abseil-cpp-61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529", + url = "https://github.com/abseil/abseil-cpp/archive/61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529.tar.gz", ) if "bazel_toolchains" not in native.existing_rules(): @@ -205,9 +205,9 @@ def grpc_deps(): if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", - sha256 = "3436ca23dc1b3345186defd0f46d64244079ba3d3234a0c5d6ef5e8d5d06c8b5", - strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77", - url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz", + sha256 = "90d6fafa8b1a2ea613bf662731d3086e1c2ed286f458a95c81744df2dbae41b1", + strip_prefix = "opencensus-cpp-c9a4da319bc669a772928ffc55af4a61be1a1176", + url = "https://github.com/census-instrumentation/opencensus-cpp/archive/c9a4da319bc669a772928ffc55af4a61be1a1176.tar.gz", ) if "upb" not in native.existing_rules(): diff --git a/tools/bazel.sh b/tools/bazel.sh index 37fd2a242bf..b0508bddbd9 100755 --- a/tools/bazel.sh +++ b/tools/bazel.sh @@ -22,7 +22,7 @@ set -e -VERSION=0.24.1 +VERSION=0.26.0 CWD=`pwd` BASEURL=https://github.com/bazelbuild/bazel/releases/download/ From f04aabc0f36e0446b9f5efb89b6d8396c83b17ab Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 5 Jun 2019 15:06:44 -0700 Subject: [PATCH 248/676] PHP: update generated code tests --- examples/node/dynamic_codegen/math_server.js | 127 ++++++++++++++++++ src/php/README.md | 4 +- .../AbstractGeneratedCodeTest.php | 2 + 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 examples/node/dynamic_codegen/math_server.js diff --git a/examples/node/dynamic_codegen/math_server.js b/examples/node/dynamic_codegen/math_server.js new file mode 100644 index 00000000000..d4eb310fc88 --- /dev/null +++ b/examples/node/dynamic_codegen/math_server.js @@ -0,0 +1,127 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var PROTO_PATH = __dirname + '/../../../src/proto/math/math.proto'; + +var grpc = require('grpc'); +var protoLoader = require('@grpc/proto-loader'); +var packageDefinition = protoLoader.loadSync( + PROTO_PATH, + {keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true + }); +var math_proto = grpc.loadPackageDefinition(packageDefinition).math; + +/** + * Implements the Div RPC method. + */ +function Div(call, callback) { + var divisor = call.request.divisor; + var dividend = call.request.dividend; + if (divisor == 0) { + callback({ + code: grpc.status.INVALID_ARGUMENT, + details: 'Cannot divide by zero' + }); + } else { + setTimeout(function () { + callback(null, { + quotient: Math.floor(dividend / divisor), + remainder: dividend % divisor + }); + }, 1); // 1 millisecond, to make sure 1 microsecond timeout from test + // will hit. TODO: Consider fixing this. + } +} + +/** + * Implements the Fib RPC method. + */ +function Fib(stream) { + var previous = 0, current = 1; + for (var i = 0; i < stream.request.limit; i++) { + stream.write({ + num: current + }); + var temp = current; + current += previous; + previous = temp; + } + stream.end(); +} + +/** + * Implements the Sum RPC method. + */ +function Sum(call, callback) { + var sum = 0; + call.on('data', function(data) { + sum += parseInt(data.num); + }); + call.on('end', function() { + callback(null, { + num: sum + }); + }); +} + +/** + * Implements the DivMany RPC method. + */ +function DivMany(stream) { + stream.on('data', function(div_args) { + var divisor = div_args.divisor; + var dividend = div_args.dividend; + if (divisor == 0) { + stream.emit('error', { + code: grpc.status.INVALID_ARGUMENT, + details: 'Cannot divide by zero' + }); + } else { + stream.write({ + quotient: Math.floor(dividend / divisor), + remainder: dividend % divisor + }); + } + }); + stream.on('end', function() { + stream.end(); + }); +} + + +/** + * Starts an RPC server that receives requests for the Math service at the + * sample server port + */ +function main() { + var server = new grpc.Server(); + server.addService(math_proto.Math.service, { + Div: Div, + Fib: Fib, + Sum: Sum, + DivMany: DivMany, + }); + server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure()); + server.start(); +} + +main(); diff --git a/src/php/README.md b/src/php/README.md index 5e9fa387636..69f4bbf42c2 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -294,9 +294,9 @@ Run a local server serving the math services. Please see [Node][] for how to run an example server. ```sh -$ cd grpc +$ cd grpc/examples/node $ npm install -$ node src/node/test/math/math_server.js +$ node dynamic_codegen/math_server.js ``` ### Run test client diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php index c050a26cbf5..8b655a7d83f 100644 --- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php +++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php @@ -81,6 +81,8 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase public function testTimeout() { $div_arg = new Math\DivArgs(); + $div_arg->setDividend(7); + $div_arg->setDivisor(4); $call = self::$client->Div($div_arg, [], ['timeout' => 1]); list($response, $status) = $call->wait(); $this->assertSame(\Grpc\STATUS_DEADLINE_EXCEEDED, $status->code); From e62d439d71c81252577419d9478dff65e6e795ae Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 5 Jun 2019 15:44:47 -0700 Subject: [PATCH 249/676] Avoid regex inefficiencies in no-match scenarios --- src/csharp/Grpc.Tools/ProtoCompile.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index 40cfbeb029b..b6fd94209d2 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -136,7 +136,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + pattern: "(?'FILENAME'[^\\(]+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -162,7 +162,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + pattern: "(?'FILENAME'[^\\(]+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -185,10 +185,10 @@ namespace Grpc.Tools // Example warning without location //../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used. - new ErrorListFilter + new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'.+): ?warning: ?(?'TEXT'.*)", + pattern: "(?'FILENAME'[^:]+): ?warning: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -211,7 +211,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'.+): ?(?'TEXT'.*)", + pattern: "(?'FILENAME'[^:]+): ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -518,7 +518,7 @@ namespace Grpc.Tools foreach (ErrorListFilter filter in s_errorListFilters) { Match match = filter.Pattern.Match(singleLine); - + if (match.Success) { filter.LogAction(Log, match); From a517c375fed5113eaf461c0f7891130b45502a0e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 5 Jun 2019 15:56:37 -0700 Subject: [PATCH 250/676] Use port server for interop tests --- src/objective-c/tests/run_one_test.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh index af8a5b6351e..04cba0e321a 100644 --- a/src/objective-c/tests/run_one_test.sh +++ b/src/objective-c/tests/run_one_test.sh @@ -27,8 +27,17 @@ BINDIR=../../../bins/$CONFIG "interop_server before calling this script." exit 1 } -$BINDIR/interop_server --port=5050 --max_send_message_size=8388608 & -$BINDIR/interop_server --port=5051 --max_send_message_size=8388608 --use_tls & + +[ -z "$(ps aux |egrep 'port_server\.py.*-p\s32766')" ] && { + echo >&2 "Can't find the port server. Start port server with tools/run_tests/start_port_server.py." + exit 1 +} + +PLAIN_PORT=$(curl localhost:32766/get) +TLS_PORT=$(curl localhost:32766/get) + +$BINDIR/interop_server --port=$PLAIN_PORT --max_send_message_size=8388608 & +$BINDIR/interop_server --port=$TLS_PORT --max_send_message_size=8388608 --use_tls & trap 'kill -9 `jobs -p` ; echo "EXIT TIME: $(date)"' EXIT @@ -40,8 +49,8 @@ xcodebuild \ -workspace Tests.xcworkspace \ -scheme SCHEME \ -destination name="iPhone 8" \ - HOST_PORT_LOCALSSL=localhost:5051 \ - HOST_PORT_LOCAL=localhost:5050 \ + HOST_PORT_LOCALSSL=localhost:$TLS_PORT \ + HOST_PORT_LOCAL=localhost:$PLAIN_PORT \ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ test \ | egrep -v "$XCODEBUILD_FILTER" \ From f2dc650f8b624de20372bb2c4abfc5d191e8fc72 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 5 Jun 2019 16:27:09 -0700 Subject: [PATCH 251/676] Do not reset outgoing buffer on failsafe path --- src/core/lib/iomgr/tcp_posix.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index cda7bba0d3a..889272f6299 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -685,7 +685,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { - grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); } From 522ddfe273b69207ec49a512b8275b560e378812 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 5 Jun 2019 16:31:39 -0700 Subject: [PATCH 252/676] Move ClientContext to grpc_impl ClientContext is another file which needs to be moved from grpc to grpc_impl for referencing it. --- BUILD | 1 + BUILD.gn | 1 + CMakeLists.txt | 5 + Makefile | 5 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/channel_impl.h | 4 +- .../grpcpp/impl/codegen/channel_interface.h | 6 +- include/grpcpp/impl/codegen/client_callback.h | 3 +- include/grpcpp/impl/codegen/client_context.h | 469 +---------------- .../grpcpp/impl/codegen/client_context_impl.h | 492 ++++++++++++++++++ .../grpcpp/impl/codegen/client_interceptor.h | 11 +- .../grpcpp/impl/codegen/client_unary_call.h | 8 +- .../impl/codegen/completion_queue_impl.h | 1 - include/grpcpp/impl/codegen/server_context.h | 4 +- src/cpp/client/client_context.cc | 11 +- test/cpp/util/cli_call.h | 6 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 20 files changed, 539 insertions(+), 494 deletions(-) create mode 100644 include/grpcpp/impl/codegen/client_context_impl.h diff --git a/BUILD b/BUILD index e0827d46cb1..4247d491fc5 100644 --- a/BUILD +++ b/BUILD @@ -2164,6 +2164,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", diff --git a/BUILD.gn b/BUILD.gn index 258cdc9f873..3041adef98a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1054,6 +1054,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index e9d2168b8de..1d3ba81ac3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3313,6 +3313,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -3932,6 +3933,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -4367,6 +4369,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -4566,6 +4569,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -4925,6 +4929,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h diff --git a/Makefile b/Makefile index e56c5ec4e47..44e18c1f474 100644 --- a/Makefile +++ b/Makefile @@ -5670,6 +5670,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6297,6 +6298,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6704,6 +6706,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6874,6 +6877,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -7239,6 +7243,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ diff --git a/build.yaml b/build.yaml index 5c085f18787..580cda1baab 100644 --- a/build.yaml +++ b/build.yaml @@ -1260,6 +1260,7 @@ filegroups: - include/grpcpp/impl/codegen/channel_interface.h - include/grpcpp/impl/codegen/client_callback.h - include/grpcpp/impl/codegen/client_context.h + - include/grpcpp/impl/codegen/client_context_impl.h - include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3b463cf7b90..861f757bb7f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -161,6 +161,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/channel_interface.h', 'include/grpcpp/impl/codegen/client_callback.h', 'include/grpcpp/impl/codegen/client_context.h', + 'include/grpcpp/impl/codegen/client_context_impl.h', 'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index 39917d2eb74..3ead8ee090e 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -85,7 +85,7 @@ class Channel final : public ::grpc::ChannelInterface, interceptor_creators); ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq) override; void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, ::grpc::internal::Call* call) override; @@ -100,7 +100,7 @@ class Channel final : public ::grpc::ChannelInterface, ::grpc::CompletionQueue* CallbackCQ() override; ::grpc::internal::Call CreateCallInternal( - const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; const grpc::string host_; diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 9df233b5500..9d0f07f3ff0 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -25,12 +25,12 @@ #include namespace grpc_impl { +class ClientContext; class CompletionQueue; } namespace grpc { class ChannelInterface; -class ClientContext; template class ClientReader; @@ -129,7 +129,7 @@ class ChannelInterface { friend class ::grpc::internal::RpcMethod; friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, - ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq) = 0; virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) = 0; @@ -149,7 +149,7 @@ class ChannelInterface { // method and adding a new pure method to an interface would be a breaking // change (even though this is private and non-API) virtual internal::Call CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) { return internal::Call(); diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index dda9aec29f3..bd438879543 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -31,12 +31,11 @@ namespace grpc_impl { class Channel; +class ClientContext; } namespace grpc { -class ClientContext; - namespace internal { class RpcMethod; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 999d8fcbfe7..8c3b669f2b7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,477 +16,14 @@ * */ -/// A ClientContext allows the person implementing a service client to: -/// -/// - Add custom metadata key-value pairs that will propagated to the server -/// side. -/// - Control call settings such as compression and authentication. -/// - Initial and trailing metadata coming from the server. -/// - Get performance metrics (ie, census). -/// -/// Context settings are only relevant to the call they are invoked with, that -/// is to say, they aren't sticky. Some of these settings, such as the -/// compression options, can be made persistent at channel construction time -/// (see \a grpc::CreateCustomChannel). -/// -/// \warning ClientContext instances should \em not be reused across rpcs. - #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H #define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct census_context; -struct grpc_call; - -namespace grpc_impl { +#include -class CallCredentials; -class Channel; -class CompletionQueue; -} // namespace grpc_impl namespace grpc { -class ChannelInterface; -class ClientContext; - -namespace internal { -class RpcMethod; -class CallOpClientRecvStatus; -class CallOpRecvInitialMetadata; -template -class BlockingUnaryCallImpl; -template -class CallbackUnaryCallImpl; -template -class ClientCallbackReaderWriterImpl; -template -class ClientCallbackReaderImpl; -template -class ClientCallbackWriterImpl; -class ClientCallbackUnaryImpl; -} // namespace internal - -template -class ClientReader; -template -class ClientWriter; -template -class ClientReaderWriter; -template -class ClientAsyncReader; -template -class ClientAsyncWriter; -template -class ClientAsyncReaderWriter; -template -class ClientAsyncResponseReader; -class ServerContext; - -/// Options for \a ClientContext::FromServerContext specifying which traits from -/// the \a ServerContext to propagate (copy) from it into a new \a -/// ClientContext. -/// -/// \see ClientContext::FromServerContext -class PropagationOptions { - public: - PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} - - PropagationOptions& enable_deadline_propagation() { - propagate_ |= GRPC_PROPAGATE_DEADLINE; - return *this; - } - - PropagationOptions& disable_deadline_propagation() { - propagate_ &= ~GRPC_PROPAGATE_DEADLINE; - return *this; - } - - PropagationOptions& enable_census_stats_propagation() { - propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; - return *this; - } - - PropagationOptions& disable_census_stats_propagation() { - propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; - return *this; - } - - PropagationOptions& enable_census_tracing_propagation() { - propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; - return *this; - } - - PropagationOptions& disable_census_tracing_propagation() { - propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; - return *this; - } - - PropagationOptions& enable_cancellation_propagation() { - propagate_ |= GRPC_PROPAGATE_CANCELLATION; - return *this; - } - - PropagationOptions& disable_cancellation_propagation() { - propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; - return *this; - } - - uint32_t c_bitmask() const { return propagate_; } - - private: - uint32_t propagate_; -}; - -namespace testing { -class InteropClientContextInspector; -} // namespace testing - -/// A ClientContext allows the person implementing a service client to: -/// -/// - Add custom metadata key-value pairs that will propagated to the server -/// side. -/// - Control call settings such as compression and authentication. -/// - Initial and trailing metadata coming from the server. -/// - Get performance metrics (ie, census). -/// -/// Context settings are only relevant to the call they are invoked with, that -/// is to say, they aren't sticky. Some of these settings, such as the -/// compression options, can be made persistent at channel construction time -/// (see \a grpc::CreateCustomChannel). -/// -/// \warning ClientContext instances should \em not be reused across rpcs. -/// \warning The ClientContext instance used for creating an rpc must remain -/// alive and valid for the lifetime of the rpc. -class ClientContext { - public: - ClientContext(); - ~ClientContext(); - - /// Create a new \a ClientContext as a child of an incoming server call, - /// according to \a options (\see PropagationOptions). - /// - /// \param server_context The source server context to use as the basis for - /// constructing the client context. - /// \param options The options controlling what to copy from the \a - /// server_context. - /// - /// \return A newly constructed \a ClientContext instance based on \a - /// server_context, with traits propagated (copied) according to \a options. - static std::unique_ptr FromServerContext( - const ServerContext& server_context, - PropagationOptions options = PropagationOptions()); - - /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with - /// a client call. These are made available at the server side by the \a - /// grpc::ServerContext::client_metadata() method. - /// - /// \warning This method should only be called before invoking the rpc. - /// - /// \param meta_key The metadata key. If \a meta_value is binary data, it must - /// end in "-bin". - /// \param meta_value The metadata value. If its value is binary, the key name - /// must end in "-bin". - /// - /// Metadata must conform to the following format: - /// Custom-Metadata -> Binary-Header / ASCII-Header - /// Binary-Header -> {Header-Name "-bin" } {binary value} - /// ASCII-Header -> Header-Name ASCII-Value - /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . - /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII - void AddMetadata(const grpc::string& meta_key, - const grpc::string& meta_value); - - /// Return a collection of initial metadata key-value pairs. Note that keys - /// may happen more than once (ie, a \a std::multimap is returned). - /// - /// \warning This method should only be called after initial metadata has been - /// received. For streaming calls, see \a - /// ClientReaderInterface::WaitForInitialMetadata(). - /// - /// \return A multimap of initial metadata key-value pairs from the server. - const std::multimap& - GetServerInitialMetadata() const { - GPR_CODEGEN_ASSERT(initial_metadata_received_); - return *recv_initial_metadata_.map(); - } - - /// Return a collection of trailing metadata key-value pairs. Note that keys - /// may happen more than once (ie, a \a std::multimap is returned). - /// - /// \warning This method is only callable once the stream has finished. - /// - /// \return A multimap of metadata trailing key-value pairs from the server. - const std::multimap& - GetServerTrailingMetadata() const { - // TODO(yangg) check finished - return *trailing_metadata_.map(); - } - - /// Set the deadline for the client call. - /// - /// \warning This method should only be called before invoking the rpc. - /// - /// \param deadline the deadline for the client call. Units are determined by - /// the type used. The deadline is an absolute (not relative) time. - template - void set_deadline(const T& deadline) { - TimePoint deadline_tp(deadline); - deadline_ = deadline_tp.raw_time(); - } - - /// EXPERIMENTAL: Indicate that this request is idempotent. - /// By default, RPCs are assumed to not be idempotent. - /// - /// If true, the gRPC library assumes that it's safe to initiate - /// this RPC multiple times. - void set_idempotent(bool idempotent) { idempotent_ = idempotent; } - - /// EXPERIMENTAL: Set this request to be cacheable. - /// If set, grpc is free to use the HTTP GET verb for sending the request, - /// with the possibility of receiving a cached response. - void set_cacheable(bool cacheable) { cacheable_ = cacheable; } - - /// EXPERIMENTAL: Trigger wait-for-ready or not on this request. - /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. - /// If set, if an RPC is made when a channel's connectivity state is - /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", - /// and the channel will wait until the channel is READY before making the - /// call. - void set_wait_for_ready(bool wait_for_ready) { - wait_for_ready_ = wait_for_ready; - wait_for_ready_explicitly_set_ = true; - } - - /// DEPRECATED: Use set_wait_for_ready() instead. - void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } - - /// Return the deadline for the client call. - std::chrono::system_clock::time_point deadline() const { - return Timespec2Timepoint(deadline_); - } - - /// Return a \a gpr_timespec representation of the client call's deadline. - gpr_timespec raw_deadline() const { return deadline_; } - - /// Set the per call authority header (see - /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). - void set_authority(const grpc::string& authority) { authority_ = authority; } - - /// Return the authentication context for this client call. - /// - /// \see grpc::AuthContext. - std::shared_ptr auth_context() const { - if (auth_context_.get() == nullptr) { - auth_context_ = CreateAuthContext(call_); - } - return auth_context_; - } - - /// Set credentials for the client call. - /// - /// A credentials object encapsulates all the state needed by a client to - /// authenticate with a server and make various assertions, e.g., about the - /// client’s identity, role, or whether it is authorized to make a particular - /// call. - /// - /// \see https://grpc.io/docs/guides/auth.html - void set_credentials( - const std::shared_ptr& creds) { - creds_ = creds; - } - - /// Return the compression algorithm the client call will request be used. - /// Note that the gRPC runtime may decide to ignore this request, for example, - /// due to resource constraints. - grpc_compression_algorithm compression_algorithm() const { - return compression_algorithm_; - } - - /// Set \a algorithm to be the compression algorithm used for the client call. - /// - /// \param algorithm The compression algorithm used for the client call. - void set_compression_algorithm(grpc_compression_algorithm algorithm); - - /// Flag whether the initial metadata should be \a corked - /// - /// If \a corked is true, then the initial metadata will be coalesced with the - /// write of first message in the stream. As a result, any tag set for the - /// initial metadata operation (starting a client-streaming or bidi-streaming - /// RPC) will not actually be sent to the completion queue or delivered - /// via Next. - /// - /// \param corked The flag indicating whether the initial metadata is to be - /// corked or not. - void set_initial_metadata_corked(bool corked) { - initial_metadata_corked_ = corked; - } - - /// Return the peer uri in a string. - /// - /// \warning This value is never authenticated or subject to any security - /// related code. It must not be used for any authentication related - /// functionality. Instead, use auth_context. - /// - /// \return The call's peer URI. - grpc::string peer() const; - - /// Get and set census context. - void set_census_context(struct census_context* ccp) { census_context_ = ccp; } - struct census_context* census_context() const { - return census_context_; - } - - /// Send a best-effort out-of-band cancel on the call associated with - /// this client context. The call could be in any stage; e.g., if it is - /// already finished, it may still return success. - /// - /// There is no guarantee the call will be cancelled. - /// - /// Note that TryCancel() does not change any of the tags that are pending - /// on the completion queue. All pending tags will still be delivered - /// (though their ok result may reflect the effect of cancellation). - void TryCancel(); - - /// Global Callbacks - /// - /// Can be set exactly once per application to install hooks whenever - /// a client context is constructed and destructed. - class GlobalCallbacks { - public: - virtual ~GlobalCallbacks() {} - virtual void DefaultConstructor(ClientContext* context) = 0; - virtual void Destructor(ClientContext* context) = 0; - }; - static void SetGlobalCallbacks(GlobalCallbacks* callbacks); - - /// Should be used for framework-level extensions only. - /// Applications never need to call this method. - grpc_call* c_call() { return call_; } - - /// EXPERIMENTAL debugging API - /// - /// if status is not ok() for an RPC, this will return a detailed string - /// of the gRPC Core error that led to the failure. It should not be relied - /// upon for anything other than gaining more debug data in failure cases. - grpc::string debug_error_string() const { return debug_error_string_; } - - private: - // Disallow copy and assign. - ClientContext(const ClientContext&); - ClientContext& operator=(const ClientContext&); - - friend class ::grpc::testing::InteropClientContextInspector; - friend class ::grpc::internal::CallOpClientRecvStatus; - friend class ::grpc::internal::CallOpRecvInitialMetadata; - friend class ::grpc_impl::Channel; - template - friend class ::grpc::ClientReader; - template - friend class ::grpc::ClientWriter; - template - friend class ::grpc::ClientReaderWriter; - template - friend class ::grpc::ClientAsyncReader; - template - friend class ::grpc::ClientAsyncWriter; - template - friend class ::grpc::ClientAsyncReaderWriter; - template - friend class ::grpc::ClientAsyncResponseReader; - template - friend class ::grpc::internal::BlockingUnaryCallImpl; - template - friend class ::grpc::internal::CallbackUnaryCallImpl; - template - friend class ::grpc::internal::ClientCallbackReaderWriterImpl; - template - friend class ::grpc::internal::ClientCallbackReaderImpl; - template - friend class ::grpc::internal::ClientCallbackWriterImpl; - friend class ::grpc::internal::ClientCallbackUnaryImpl; - - // Used by friend class CallOpClientRecvStatus - void set_debug_error_string(const grpc::string& debug_error_string) { - debug_error_string_ = debug_error_string; - } - - grpc_call* call() const { return call_; } - void set_call(grpc_call* call, - const std::shared_ptr<::grpc_impl::Channel>& channel); - - experimental::ClientRpcInfo* set_client_rpc_info( - const char* method, internal::RpcMethod::RpcType type, - grpc::ChannelInterface* channel, - const std::vector< - std::unique_ptr>& - creators, - size_t interceptor_pos) { - rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel); - rpc_info_.RegisterInterceptors(creators, interceptor_pos); - return &rpc_info_; - } - - uint32_t initial_metadata_flags() const { - return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) | - (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | - (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) | - (wait_for_ready_explicitly_set_ - ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET - : 0) | - (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0); - } - - grpc::string authority() { return authority_; } - - void SendCancelToInterceptors(); - - bool initial_metadata_received_; - bool wait_for_ready_; - bool wait_for_ready_explicitly_set_; - bool idempotent_; - bool cacheable_; - std::shared_ptr<::grpc_impl::Channel> channel_; - grpc::internal::Mutex mu_; - grpc_call* call_; - bool call_canceled_; - gpr_timespec deadline_; - grpc::string authority_; - std::shared_ptr creds_; - mutable std::shared_ptr auth_context_; - struct census_context* census_context_; - std::multimap send_initial_metadata_; - mutable internal::MetadataMap recv_initial_metadata_; - mutable internal::MetadataMap trailing_metadata_; - - grpc_call* propagate_from_call_; - PropagationOptions propagation_options_; - - grpc_compression_algorithm compression_algorithm_; - bool initial_metadata_corked_; - - grpc::string debug_error_string_; - - experimental::ClientRpcInfo rpc_info_; -}; +typedef ::grpc_impl::ClientContext ClientContext; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_context_impl.h b/include/grpcpp/impl/codegen/client_context_impl.h new file mode 100644 index 00000000000..76655c63d31 --- /dev/null +++ b/include/grpcpp/impl/codegen/client_context_impl.h @@ -0,0 +1,492 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/// A ClientContext allows the person implementing a service client to: +/// +/// - Add custom metadata key-value pairs that will propagated to the server +/// side. +/// - Control call settings such as compression and authentication. +/// - Initial and trailing metadata coming from the server. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call they are invoked with, that +/// is to say, they aren't sticky. Some of these settings, such as the +/// compression options, can be made persistent at channel construction time +/// (see \a grpc::CreateCustomChannel). +/// +/// \warning ClientContext instances should \em not be reused across rpcs. + +#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_IMPL_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_IMPL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct census_context; +struct grpc_call; + +namespace grpc { + +class ChannelInterface; + +namespace internal { +class RpcMethod; +class CallOpClientRecvStatus; +class CallOpRecvInitialMetadata; +template +class BlockingUnaryCallImpl; +template +class CallbackUnaryCallImpl; +template +class ClientCallbackReaderWriterImpl; +template +class ClientCallbackReaderImpl; +template +class ClientCallbackWriterImpl; +class ClientCallbackUnaryImpl; +} // namespace internal + +template +class ClientReader; +template +class ClientWriter; +template +class ClientReaderWriter; +template +class ClientAsyncReader; +template +class ClientAsyncWriter; +template +class ClientAsyncReaderWriter; +template +class ClientAsyncResponseReader; +class ServerContext; + +namespace testing { +class InteropClientContextInspector; +} // namespace testing +} // namespace grpc +namespace grpc_impl { + +class CallCredentials; +class Channel; +class CompletionQueue; + +/// Options for \a ClientContext::FromServerContext specifying which traits from +/// the \a ServerContext to propagate (copy) from it into a new \a +/// ClientContext. +/// +/// \see ClientContext::FromServerContext +class PropagationOptions { + public: + PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {} + + PropagationOptions& enable_deadline_propagation() { + propagate_ |= GRPC_PROPAGATE_DEADLINE; + return *this; + } + + PropagationOptions& disable_deadline_propagation() { + propagate_ &= ~GRPC_PROPAGATE_DEADLINE; + return *this; + } + + PropagationOptions& enable_census_stats_propagation() { + propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; + return *this; + } + + PropagationOptions& disable_census_stats_propagation() { + propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT; + return *this; + } + + PropagationOptions& enable_census_tracing_propagation() { + propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; + return *this; + } + + PropagationOptions& disable_census_tracing_propagation() { + propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT; + return *this; + } + + PropagationOptions& enable_cancellation_propagation() { + propagate_ |= GRPC_PROPAGATE_CANCELLATION; + return *this; + } + + PropagationOptions& disable_cancellation_propagation() { + propagate_ &= ~GRPC_PROPAGATE_CANCELLATION; + return *this; + } + + uint32_t c_bitmask() const { return propagate_; } + + private: + uint32_t propagate_; +}; + +/// A ClientContext allows the person implementing a service client to: +/// +/// - Add custom metadata key-value pairs that will propagated to the server +/// side. +/// - Control call settings such as compression and authentication. +/// - Initial and trailing metadata coming from the server. +/// - Get performance metrics (ie, census). +/// +/// Context settings are only relevant to the call they are invoked with, that +/// is to say, they aren't sticky. Some of these settings, such as the +/// compression options, can be made persistent at channel construction time +/// (see \a grpc::CreateCustomChannel). +/// +/// \warning ClientContext instances should \em not be reused across rpcs. +/// \warning The ClientContext instance used for creating an rpc must remain +/// alive and valid for the lifetime of the rpc. +class ClientContext { + public: + ClientContext(); + ~ClientContext(); + + /// Create a new \a ClientContext as a child of an incoming server call, + /// according to \a options (\see PropagationOptions). + /// + /// \param server_context The source server context to use as the basis for + /// constructing the client context. + /// \param options The options controlling what to copy from the \a + /// server_context. + /// + /// \return A newly constructed \a ClientContext instance based on \a + /// server_context, with traits propagated (copied) according to \a options. + static std::unique_ptr FromServerContext( + const grpc::ServerContext& server_context, + PropagationOptions options = PropagationOptions()); + + /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with + /// a client call. These are made available at the server side by the \a + /// grpc::ServerContext::client_metadata() method. + /// + /// \warning This method should only be called before invoking the rpc. + /// + /// \param meta_key The metadata key. If \a meta_value is binary data, it must + /// end in "-bin". + /// \param meta_value The metadata value. If its value is binary, the key name + /// must end in "-bin". + /// + /// Metadata must conform to the following format: + /// Custom-Metadata -> Binary-Header / ASCII-Header + /// Binary-Header -> {Header-Name "-bin" } {binary value} + /// ASCII-Header -> Header-Name ASCII-Value + /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - . + /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII + void AddMetadata(const grpc::string& meta_key, + const grpc::string& meta_value); + + /// Return a collection of initial metadata key-value pairs. Note that keys + /// may happen more than once (ie, a \a std::multimap is returned). + /// + /// \warning This method should only be called after initial metadata has been + /// received. For streaming calls, see \a + /// ClientReaderInterface::WaitForInitialMetadata(). + /// + /// \return A multimap of initial metadata key-value pairs from the server. + const std::multimap& + GetServerInitialMetadata() const { + GPR_CODEGEN_ASSERT(initial_metadata_received_); + return *recv_initial_metadata_.map(); + } + + /// Return a collection of trailing metadata key-value pairs. Note that keys + /// may happen more than once (ie, a \a std::multimap is returned). + /// + /// \warning This method is only callable once the stream has finished. + /// + /// \return A multimap of metadata trailing key-value pairs from the server. + const std::multimap& + GetServerTrailingMetadata() const { + // TODO(yangg) check finished + return *trailing_metadata_.map(); + } + + /// Set the deadline for the client call. + /// + /// \warning This method should only be called before invoking the rpc. + /// + /// \param deadline the deadline for the client call. Units are determined by + /// the type used. The deadline is an absolute (not relative) time. + template + void set_deadline(const T& deadline) { + grpc::TimePoint deadline_tp(deadline); + deadline_ = deadline_tp.raw_time(); + } + + /// EXPERIMENTAL: Indicate that this request is idempotent. + /// By default, RPCs are assumed to not be idempotent. + /// + /// If true, the gRPC library assumes that it's safe to initiate + /// this RPC multiple times. + void set_idempotent(bool idempotent) { idempotent_ = idempotent; } + + /// EXPERIMENTAL: Set this request to be cacheable. + /// If set, grpc is free to use the HTTP GET verb for sending the request, + /// with the possibility of receiving a cached response. + void set_cacheable(bool cacheable) { cacheable_ = cacheable; } + + /// EXPERIMENTAL: Trigger wait-for-ready or not on this request. + /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. + /// If set, if an RPC is made when a channel's connectivity state is + /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast", + /// and the channel will wait until the channel is READY before making the + /// call. + void set_wait_for_ready(bool wait_for_ready) { + wait_for_ready_ = wait_for_ready; + wait_for_ready_explicitly_set_ = true; + } + + /// DEPRECATED: Use set_wait_for_ready() instead. + void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); } + + /// Return the deadline for the client call. + std::chrono::system_clock::time_point deadline() const { + return grpc::Timespec2Timepoint(deadline_); + } + + /// Return a \a gpr_timespec representation of the client call's deadline. + gpr_timespec raw_deadline() const { return deadline_; } + + /// Set the per call authority header (see + /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3). + void set_authority(const grpc::string& authority) { authority_ = authority; } + + /// Return the authentication context for this client call. + /// + /// \see grpc::AuthContext. + std::shared_ptr auth_context() const { + if (auth_context_.get() == nullptr) { + auth_context_ = grpc::CreateAuthContext(call_); + } + return auth_context_; + } + + /// Set credentials for the client call. + /// + /// A credentials object encapsulates all the state needed by a client to + /// authenticate with a server and make various assertions, e.g., about the + /// client’s identity, role, or whether it is authorized to make a particular + /// call. + /// + /// \see https://grpc.io/docs/guides/auth.html + void set_credentials( + const std::shared_ptr& creds) { + creds_ = creds; + } + + /// Return the compression algorithm the client call will request be used. + /// Note that the gRPC runtime may decide to ignore this request, for example, + /// due to resource constraints. + grpc_compression_algorithm compression_algorithm() const { + return compression_algorithm_; + } + + /// Set \a algorithm to be the compression algorithm used for the client call. + /// + /// \param algorithm The compression algorithm used for the client call. + void set_compression_algorithm(grpc_compression_algorithm algorithm); + + /// Flag whether the initial metadata should be \a corked + /// + /// If \a corked is true, then the initial metadata will be coalesced with the + /// write of first message in the stream. As a result, any tag set for the + /// initial metadata operation (starting a client-streaming or bidi-streaming + /// RPC) will not actually be sent to the completion queue or delivered + /// via Next. + /// + /// \param corked The flag indicating whether the initial metadata is to be + /// corked or not. + void set_initial_metadata_corked(bool corked) { + initial_metadata_corked_ = corked; + } + + /// Return the peer uri in a string. + /// + /// \warning This value is never authenticated or subject to any security + /// related code. It must not be used for any authentication related + /// functionality. Instead, use auth_context. + /// + /// \return The call's peer URI. + grpc::string peer() const; + + /// Get and set census context. + void set_census_context(struct census_context* ccp) { census_context_ = ccp; } + struct census_context* census_context() const { + return census_context_; + } + + /// Send a best-effort out-of-band cancel on the call associated with + /// this client context. The call could be in any stage; e.g., if it is + /// already finished, it may still return success. + /// + /// There is no guarantee the call will be cancelled. + /// + /// Note that TryCancel() does not change any of the tags that are pending + /// on the completion queue. All pending tags will still be delivered + /// (though their ok result may reflect the effect of cancellation). + void TryCancel(); + + /// Global Callbacks + /// + /// Can be set exactly once per application to install hooks whenever + /// a client context is constructed and destructed. + class GlobalCallbacks { + public: + virtual ~GlobalCallbacks() {} + virtual void DefaultConstructor(ClientContext* context) = 0; + virtual void Destructor(ClientContext* context) = 0; + }; + static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + + /// Should be used for framework-level extensions only. + /// Applications never need to call this method. + grpc_call* c_call() { return call_; } + + /// EXPERIMENTAL debugging API + /// + /// if status is not ok() for an RPC, this will return a detailed string + /// of the gRPC Core error that led to the failure. It should not be relied + /// upon for anything other than gaining more debug data in failure cases. + grpc::string debug_error_string() const { return debug_error_string_; } + + private: + // Disallow copy and assign. + ClientContext(const ClientContext&); + ClientContext& operator=(const ClientContext&); + + friend class ::grpc::testing::InteropClientContextInspector; + friend class ::grpc::internal::CallOpClientRecvStatus; + friend class ::grpc::internal::CallOpRecvInitialMetadata; + friend class ::grpc_impl::Channel; + template + friend class ::grpc::ClientReader; + template + friend class ::grpc::ClientWriter; + template + friend class ::grpc::ClientReaderWriter; + template + friend class ::grpc::ClientAsyncReader; + template + friend class ::grpc::ClientAsyncWriter; + template + friend class ::grpc::ClientAsyncReaderWriter; + template + friend class ::grpc::ClientAsyncResponseReader; + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + template + friend class ::grpc::internal::CallbackUnaryCallImpl; + template + friend class ::grpc::internal::ClientCallbackReaderWriterImpl; + template + friend class ::grpc::internal::ClientCallbackReaderImpl; + template + friend class ::grpc::internal::ClientCallbackWriterImpl; + friend class ::grpc::internal::ClientCallbackUnaryImpl; + + // Used by friend class CallOpClientRecvStatus + void set_debug_error_string(const grpc::string& debug_error_string) { + debug_error_string_ = debug_error_string; + } + + grpc_call* call() const { return call_; } + void set_call(grpc_call* call, + const std::shared_ptr<::grpc_impl::Channel>& channel); + + grpc::experimental::ClientRpcInfo* set_client_rpc_info( + const char* method, grpc::internal::RpcMethod::RpcType type, + grpc::ChannelInterface* channel, + const std::vector< + std::unique_ptr>& + creators, + size_t interceptor_pos) { + rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method, channel); + rpc_info_.RegisterInterceptors(creators, interceptor_pos); + return &rpc_info_; + } + + uint32_t initial_metadata_flags() const { + return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) | + (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) | + (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) | + (wait_for_ready_explicitly_set_ + ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET + : 0) | + (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0); + } + + grpc::string authority() { return authority_; } + + void SendCancelToInterceptors(); + + bool initial_metadata_received_; + bool wait_for_ready_; + bool wait_for_ready_explicitly_set_; + bool idempotent_; + bool cacheable_; + std::shared_ptr<::grpc_impl::Channel> channel_; + grpc::internal::Mutex mu_; + grpc_call* call_; + bool call_canceled_; + gpr_timespec deadline_; + grpc::string authority_; + std::shared_ptr creds_; + mutable std::shared_ptr auth_context_; + struct census_context* census_context_; + std::multimap send_initial_metadata_; + mutable grpc::internal::MetadataMap recv_initial_metadata_; + mutable grpc::internal::MetadataMap trailing_metadata_; + + grpc_call* propagate_from_call_; + PropagationOptions propagation_options_; + + grpc_compression_algorithm compression_algorithm_; + bool initial_metadata_corked_; + + grpc::string debug_error_string_; + + grpc::experimental::ClientRpcInfo rpc_info_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index a4c85a76da5..c0269edb16e 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -29,12 +29,11 @@ namespace grpc_impl { class Channel; +class ClientContext; } namespace grpc { -class ClientContext; - namespace internal { class InterceptorBatchMethodsImpl; } @@ -96,7 +95,7 @@ class ClientRpcInfo { /// Return a pointer to the underlying ClientContext structure associated /// with the RPC to support features that apply to it - grpc::ClientContext* client_context() { return ctx_; } + grpc_impl::ClientContext* client_context() { return ctx_; } /// Return the type of the RPC (unary or a streaming flavor) Type type() const { return type_; } @@ -119,7 +118,7 @@ class ClientRpcInfo { ClientRpcInfo() = default; // Constructor will only be called from ClientContext - ClientRpcInfo(grpc::ClientContext* ctx, internal::RpcMethod::RpcType type, + ClientRpcInfo(grpc_impl::ClientContext* ctx, internal::RpcMethod::RpcType type, const char* method, grpc::ChannelInterface* channel) : ctx_(ctx), type_(static_cast(type)), @@ -160,7 +159,7 @@ class ClientRpcInfo { } } - grpc::ClientContext* ctx_ = nullptr; + grpc_impl::ClientContext* ctx_ = nullptr; // TODO(yashykt): make type_ const once move-assignment is deleted Type type_{Type::UNKNOWN}; const char* method_ = nullptr; @@ -170,7 +169,7 @@ class ClientRpcInfo { size_t hijacked_interceptor_ = 0; friend class internal::InterceptorBatchMethodsImpl; - friend class grpc::ClientContext; + friend class grpc_impl::ClientContext; }; // PLEASE DO NOT USE THIS. ALWAYS PREFER PER CHANNEL INTERCEPTORS OVER A GLOBAL diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index e0f692b1783..d312aacf036 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -25,16 +25,18 @@ #include #include -namespace grpc { +namespace grpc_impl { class ClientContext; +} // namespace grpc_impl +namespace grpc { namespace internal { class RpcMethod; /// Wrapper that performs a blocking unary call template Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage& request, + grpc_impl::ClientContext* context, const InputMessage& request, OutputMessage* result) { return BlockingUnaryCallImpl( channel, method, context, request, result) @@ -45,7 +47,7 @@ template class BlockingUnaryCallImpl { public: BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage& request, + grpc_impl::ClientContext* context, const InputMessage& request, OutputMessage* result) { CompletionQueue cq(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index d5c4bb0f201..d78c410704a 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -65,7 +65,6 @@ class ServerReaderWriterBody; } // namespace internal class ChannelInterface; -class ClientContext; class ServerContext; class ServerInterface; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index c6903743938..7f3280b3d4c 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -43,11 +43,11 @@ struct census_context; namespace grpc_impl { +class ClientContext; class CompletionQueue; class Server; } // namespace grpc_impl namespace grpc { -class ClientContext; class GenericServerContext; class ServerInterface; template @@ -306,7 +306,7 @@ class ServerContext { friend class ::grpc::internal::CallbackBidiHandler; template friend class internal::ErrorMethodHandler; - friend class ::grpc::ClientContext; + friend class ::grpc_impl::ClientContext; friend class ::grpc::GenericServerContext; /// Prevent copying. diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index 0ae1ecbf4ba..efb10a44006 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -34,9 +34,6 @@ namespace grpc_impl { class Channel; -} - -namespace grpc { class DefaultGlobalClientCallbacks final : public ClientContext::GlobalCallbacks { @@ -46,7 +43,7 @@ class DefaultGlobalClientCallbacks final void Destructor(ClientContext* context) override {} }; -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; static DefaultGlobalClientCallbacks* g_default_client_callbacks = new DefaultGlobalClientCallbacks(); static ClientContext::GlobalCallbacks* g_client_callbacks = @@ -76,7 +73,7 @@ ClientContext::~ClientContext() { } std::unique_ptr ClientContext::FromServerContext( - const ServerContext& context, PropagationOptions options) { + const grpc::ServerContext& context, PropagationOptions options) { std::unique_ptr ctx(new ClientContext); ctx->propagate_from_call_ = context.call_; ctx->propagation_options_ = options; @@ -130,7 +127,7 @@ void ClientContext::TryCancel() { } void ClientContext::SendCancelToInterceptors() { - internal::CancelInterceptorBatchMethods cancel_methods; + grpc::internal::CancelInterceptorBatchMethods cancel_methods; for (size_t i = 0; i < rpc_info_.interceptors_.size(); i++) { rpc_info_.RunInterceptor(&cancel_methods, i); } @@ -153,4 +150,4 @@ void ClientContext::SetGlobalCallbacks(GlobalCallbacks* client_callbacks) { g_client_callbacks = client_callbacks; } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h index 3f279095a42..65144a1892c 100644 --- a/test/cpp/util/cli_call.h +++ b/test/cpp/util/cli_call.h @@ -27,9 +27,11 @@ #include #include -namespace grpc { +namespace grpc_impl { class ClientContext; +} // namespace grpc_impl +namespace grpc { namespace testing { @@ -85,7 +87,7 @@ class CliCall final { private: std::unique_ptr stub_; - grpc::ClientContext ctx_; + grpc_impl::ClientContext ctx_; std::unique_ptr call_; grpc::CompletionQueue cq_; gpr_mu write_mu_; diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 913d7be993b..3daf46f580c 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -956,6 +956,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8b664d8ac01..0bf0682fb7e 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -957,6 +957,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a479a00509a..a9a5a372128 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10130,6 +10130,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", @@ -10208,6 +10209,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", From 7e18e6cf3fe6a93166b67d0614f5b69791887a63 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 5 Jun 2019 16:47:29 -0700 Subject: [PATCH 253/676] Fix clang errors. --- include/grpcpp/channel_impl.h | 5 +++-- include/grpcpp/impl/codegen/channel_interface.h | 2 +- include/grpcpp/impl/codegen/client_callback.h | 2 +- include/grpcpp/impl/codegen/client_context_impl.h | 5 ++--- include/grpcpp/impl/codegen/client_interceptor.h | 7 ++++--- include/grpcpp/impl/codegen/client_unary_call.h | 8 ++++---- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index 3ead8ee090e..a7eee2b8981 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -100,8 +100,9 @@ class Channel final : public ::grpc::ChannelInterface, ::grpc::CompletionQueue* CallbackCQ() override; ::grpc::internal::Call CreateCallInternal( - const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, - ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq, + size_t interceptor_pos) override; const grpc::string host_; grpc_channel* const c_channel_; // owned diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 9d0f07f3ff0..836c287e509 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -27,7 +27,7 @@ namespace grpc_impl { class ClientContext; class CompletionQueue; -} +} // namespace grpc_impl namespace grpc { class ChannelInterface; diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index bd438879543..6cba5830e4b 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -32,7 +32,7 @@ namespace grpc_impl { class Channel; class ClientContext; -} +} // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/impl/codegen/client_context_impl.h b/include/grpcpp/impl/codegen/client_context_impl.h index 76655c63d31..e730450a5c9 100644 --- a/include/grpcpp/impl/codegen/client_context_impl.h +++ b/include/grpcpp/impl/codegen/client_context_impl.h @@ -435,9 +435,8 @@ class ClientContext { grpc::experimental::ClientRpcInfo* set_client_rpc_info( const char* method, grpc::internal::RpcMethod::RpcType type, grpc::ChannelInterface* channel, - const std::vector< - std::unique_ptr>& - creators, + const std::vector>& creators, size_t interceptor_pos) { rpc_info_ = grpc::experimental::ClientRpcInfo(this, type, method, channel); rpc_info_.RegisterInterceptors(creators, interceptor_pos); diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index c0269edb16e..9e978b6a53e 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -30,7 +30,7 @@ namespace grpc_impl { class Channel; class ClientContext; -} +} // namespace grpc_impl namespace grpc { @@ -118,8 +118,9 @@ class ClientRpcInfo { ClientRpcInfo() = default; // Constructor will only be called from ClientContext - ClientRpcInfo(grpc_impl::ClientContext* ctx, internal::RpcMethod::RpcType type, - const char* method, grpc::ChannelInterface* channel) + ClientRpcInfo(grpc_impl::ClientContext* ctx, + internal::RpcMethod::RpcType type, const char* method, + grpc::ChannelInterface* channel) : ctx_(ctx), type_(static_cast(type)), method_(method), diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index d312aacf036..599dd1ecac9 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -36,8 +36,8 @@ class RpcMethod; /// Wrapper that performs a blocking unary call template Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method, - grpc_impl::ClientContext* context, const InputMessage& request, - OutputMessage* result) { + grpc_impl::ClientContext* context, + const InputMessage& request, OutputMessage* result) { return BlockingUnaryCallImpl( channel, method, context, request, result) .status(); @@ -47,8 +47,8 @@ template class BlockingUnaryCallImpl { public: BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - grpc_impl::ClientContext* context, const InputMessage& request, - OutputMessage* result) { + grpc_impl::ClientContext* context, + const InputMessage& request, OutputMessage* result) { CompletionQueue cq(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, nullptr}); // Pluckable completion queue From 7bf845aeefaa68ae2db2d71ffc0723002541dc63 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 5 Jun 2019 23:42:56 -0400 Subject: [PATCH 254/676] Do not intern method and host for registered methods. Registered methods already have a strdup() of host and method. Since we have the copy, the strings are guaranteed to remain valid. --- src/core/lib/surface/server.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 44de0cd42dd..8f6df482aa9 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1194,12 +1194,12 @@ void grpc_server_setup_transport( bool has_host; grpc_slice method; if (rm->host != nullptr) { - host = grpc_slice_intern(grpc_slice_from_static_string(rm->host)); + host = grpc_slice_from_static_string(rm->host); has_host = true; } else { has_host = false; } - method = grpc_slice_intern(grpc_slice_from_static_string(rm->method)); + method = grpc_slice_from_static_string(rm->method); hash = GRPC_MDSTR_KV_HASH(has_host ? grpc_slice_hash_internal(host) : 0, grpc_slice_hash_internal(method)); for (probes = 0; chand->registered_methods[(hash + probes) % slots] From c43b77b73838e110cb67b6a3250bd3dba0c14bf8 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 5 Jun 2019 21:40:17 -0700 Subject: [PATCH 255/676] Add tests for allowing dots in metadata keys --- .../AbstractGeneratedCodeTest.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php index c050a26cbf5..f7b47359992 100644 --- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php +++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php @@ -71,6 +71,33 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase $call = self::$client->Div($div_arg, [' ' => 'abc123']); } + public function testMetadata() + { + $div_arg = new Math\DivArgs(); + $call = self::$client->Div($div_arg, ['somekey' => ['abc123']]); + } + + public function testMetadataKey() + { + $div_arg = new Math\DivArgs(); + $call = self::$client->Div($div_arg, ['somekey_-1' => ['abc123']]); + } + + public function testMetadataKeyWithDot() + { + $div_arg = new Math\DivArgs(); + $call = self::$client->Div($div_arg, ['someKEY._-1' => ['abc123']]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testMetadataInvalidKey() + { + $div_arg = new Math\DivArgs(); + $call = self::$client->Div($div_arg, ['(somekey)' => ['abc123']]); + } + public function testGetCallMetadata() { $div_arg = new Math\DivArgs(); @@ -81,6 +108,8 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase public function testTimeout() { $div_arg = new Math\DivArgs(); + $div_arg->setDividend(7); + $div_arg->setDivisor(4); $call = self::$client->Div($div_arg, [], ['timeout' => 1]); list($response, $status) = $call->wait(); $this->assertSame(\Grpc\STATUS_DEADLINE_EXCEEDED, $status->code); From bf4c7f45ef9dc63306bbd6ef9461ed0646a0b843 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Jun 2019 08:58:41 -0400 Subject: [PATCH 256/676] use bazelisk to grab latest bazel version --- .../linux/grpc_bazel_rbe_incompatible_changes.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh index 9c3712a07da..85b82443bcd 100644 --- a/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh +++ b/tools/internal_ci/linux/grpc_bazel_rbe_incompatible_changes.sh @@ -15,9 +15,14 @@ set -ex -# TODO(jtattermusch): use the latest version of bazel +# Use bazelisk to download the right bazel version +wget https://github.com/bazelbuild/bazelisk/releases/download/v0.0.7/bazelisk-linux-amd64 +chmod u+x bazelisk-linux-amd64 -# Use --all_incompatible_changes to give an early warning about future -# bazel incompatibilities. -EXTRA_FLAGS="--config=opt --cache_test_results=no --all_incompatible_changes" +# We want bazelisk to run the latest stable version +export USE_BAZEL_VERSION=latest +# Use bazelisk instead of our usual //tools/bazel wrapper +mv bazelisk-linux-amd64 github/grpc/tools/bazel + +EXTRA_FLAGS="--config=opt --cache_test_results=no" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" From 957e71ecd29f03dd4c37aa89834c4f6d97b3f6ae Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Jun 2019 16:13:47 +0200 Subject: [PATCH 257/676] add config for C/C++ build only PR job --- .../grpc_basictests_c_cpp_build_only.cfg | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_build_only.cfg diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_build_only.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_build_only.cfg new file mode 100644 index 00000000000..0eb27206eeb --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_build_only.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux corelang --inner_jobs 16 -j 1 --internal_ci --build_only" +} From e7aca312fc9187e959e59703a68dbc313ee73b8e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Jun 2019 10:25:37 -0700 Subject: [PATCH 258/676] Stop misspelling our own project name --- src/core/ext/filters/client_channel/resolver.h | 2 +- src/core/lib/channel/channelz_registry.h | 4 ++-- src/core/lib/gprpp/memory.h | 4 ++-- src/core/lib/gprpp/orphanable.h | 2 +- src/core/lib/gprpp/ref_counted.h | 6 +++--- src/core/lib/iomgr/buffer_list.h | 2 +- src/core/lib/slice/slice.cc | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 9aa504225ad..87a4442d75b 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -128,7 +128,7 @@ class Resolver : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE /// Does NOT take ownership of the reference to \a combiner. // TODO(roth): Once we have a C++-like interface for combiners, this diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index aa87b64e5b2..b9d42ecf4d6 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -69,8 +69,8 @@ class ChannelzRegistry { static void LogAllEntities() { Default()->InternalLogAllEntities(); } private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE friend class testing::ChannelzRegistryPeer; ChannelzRegistry(); diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index b4b63ae771a..70ad430c51d 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -29,12 +29,12 @@ // Add this to a class that want to use Delete(), but has a private or // protected destructor. -#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ template \ friend void grpc_core::Delete(T*); // Add this to a class that want to use New(), but has a private or // protected constructor. -#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ template \ friend T* grpc_core::New(Args&&...); diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 2e467e49060..82350a19a2c 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -84,7 +84,7 @@ class InternallyRefCounted : public Orphanable { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE // Allow RefCountedPtr<> to access Unref() and IncrementRefCount(). template diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 392c12a3bd1..cab1aaaaab1 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -44,7 +44,7 @@ class PolymorphicRefCount { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE virtual ~PolymorphicRefCount() = default; }; @@ -57,7 +57,7 @@ class NonPolymorphicRefCount { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE ~NonPolymorphicRefCount() = default; }; @@ -233,7 +233,7 @@ class RefCounted : public Impl { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. // Note: RefCount tracing is only enabled on debug builds, even when a diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 8bb271867c2..755ce02ba95 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -133,7 +133,7 @@ class TracedBuffer { grpc_error* shutdown_err); private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW TracedBuffer(uint32_t seq_no, void* arg) : seq_no_(seq_no), arg_(arg), next_(nullptr) {} diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 3a3edebdc7a..566ad94d705 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -106,7 +106,7 @@ class NewSliceRefcount { user_destroy_(destroy), user_data_(user_data) {} - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE grpc_slice_refcount* base_refcount() { return &rc_; } @@ -155,7 +155,7 @@ class NewWithLenSliceRefcount { user_length_(user_length), user_destroy_(destroy) {} - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE grpc_slice_refcount* base_refcount() { return &rc_; } From 22daa0de6f4ed97c501355c25c331ba59df0c7a0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Jun 2019 13:45:51 -0400 Subject: [PATCH 259/676] remove unused objc interop tests configs --- tools/internal_ci/macos/grpc_interop.cfg | 26 -------------------- tools/internal_ci/macos/grpc_interop.sh | 31 ------------------------ 2 files changed, 57 deletions(-) delete mode 100644 tools/internal_ci/macos/grpc_interop.cfg delete mode 100755 tools/internal_ci/macos/grpc_interop.sh diff --git a/tools/internal_ci/macos/grpc_interop.cfg b/tools/internal_ci/macos/grpc_interop.cfg deleted file mode 100644 index 434ecd19c4d..00000000000 --- a/tools/internal_ci/macos/grpc_interop.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Config file for the internal CI (in protobuf text format) - -# Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/macos/grpc_interop.sh" -gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" -timeout_mins: 240 -action { - define_artifacts { - regex: "**/*sponge_log.*" - regex: "github/grpc/reports/**" - } -} diff --git a/tools/internal_ci/macos/grpc_interop.sh b/tools/internal_ci/macos/grpc_interop.sh deleted file mode 100755 index e290ed60c47..00000000000 --- a/tools/internal_ci/macos/grpc_interop.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -ex - -# change to grpc repo root -cd $(dirname $0)/../../.. - -source tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc -source tools/internal_ci/helper_scripts/prepare_build_macos_rc - -tools/run_tests/run_interop_tests.py -l objc -s all --use_docker -t -j 1 || FAILED="true" - -tools/internal_ci/helper_scripts/delete_nonartifacts.sh || true - -if [ "$FAILED" != "" ] -then - exit 1 -fi From ed045828b9e66108ae0f3b2da08a19017ab1329e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Jun 2019 14:12:55 -0400 Subject: [PATCH 260/676] make default service account email configurable --- tools/run_tests/run_interop_tests.py | 35 ++++++++++++++++------------ 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 96e5ee340fc..e71d308dcbe 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -807,23 +807,17 @@ def compute_engine_creds_required(language, test_case): return False -def auth_options(language, - test_case, - google_default_creds_use_key_file, - service_account_key_file=None): +def auth_options(language, test_case, google_default_creds_use_key_file, + service_account_key_file, default_service_account): """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" language = str(language) cmdargs = [] env = {} - if not service_account_key_file: - # this file path only works inside docker - service_account_key_file = '/root/service_account/grpc-testing-ebe7c1ac7381.json' oauth_scope_arg = '--oauth_scope=https://www.googleapis.com/auth/xapi.zoo' key_file_arg = '--service_account_key_file=%s' % service_account_key_file - # default compute engine credentials associated with the testing VMs in "grpc-testing" cloud project - default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' + default_account_arg = '--default_service_account=%s' % default_service_account if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: if language in [ @@ -874,6 +868,7 @@ def cloud_to_prod_jobspec(language, auth=False, manual_cmd_log=None, service_account_key_file=None, + default_service_account=None, transport_security='tls'): """Creates jobspec for cloud-to-prod interop test""" container_name = None @@ -901,9 +896,9 @@ def cloud_to_prod_jobspec(language, cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) if auth: - auth_cmdargs, auth_env = auth_options(language, test_case, - google_default_creds_use_key_file, - service_account_key_file) + auth_cmdargs, auth_env = auth_options( + language, test_case, google_default_creds_use_key_file, + service_account_key_file, default_service_account) cmdargs += auth_cmdargs environ.update(auth_env) cmdline = bash_cmdline(language.client_cmd(cmdargs)) @@ -1212,12 +1207,17 @@ argp.add_argument( help= 'Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000', default=[]) +# TODO(jtattermusch): the default service_account_key_file only works when --use_docker is used. argp.add_argument( '--service_account_key_file', type=str, - help= - 'Override the default service account key file to use for auth interop tests.', - default=None) + help='The service account key file to use for some auth interop tests.', + default='/root/service_account/grpc-testing-ebe7c1ac7381.json') +argp.add_argument( + '--default_service_account', + type=str, + help='Default GCE service account email to use for some auth interop tests.', + default='830293263384-compute@developer.gserviceaccount.com') argp.add_argument( '-t', '--travis', default=False, action='store_const', const=True) argp.add_argument( @@ -1470,6 +1470,8 @@ try: manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. service_account_key_file, + default_service_account=args. + default_service_account, transport_security=transport_security) jobs.append(test_job) if args.http2_interop: @@ -1484,6 +1486,7 @@ try: docker_image=docker_images.get(str(http2Interop)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args.service_account_key_file, + default_service_account=args.default_service_account, transport_security=args.transport_security) jobs.append(test_job) @@ -1517,6 +1520,8 @@ try: manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. service_account_key_file, + default_service_account=args. + default_service_account, transport_security=transport_security) jobs.append(test_job) for server in args.override_server: From 7f72d114df4ec6ee336ce1e994b8b3dfbe29160d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 6 Jun 2019 14:13:19 -0400 Subject: [PATCH 261/676] fix macos interop toprod tests --- tools/internal_ci/macos/grpc_interop_toprod.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index 36e5a2103d9..13bf58ad1b2 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -34,6 +34,7 @@ tools/run_tests/run_interop_tests.py -l c++ \ --google_default_creds_use_key_file \ --prod_servers default gateway_v4 \ --service_account_key_file="${KOKORO_KEYSTORE_DIR}/73836_interop_to_prod_tests_service_account_key" \ + --default_service_account="interop-to-prod-tests@grpc-testing.iam.gserviceaccount.com" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" tools/internal_ci/helper_scripts/delete_nonartifacts.sh || true From 7994ea53fcd956f4c1745814e8dd09aae2113693 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 6 Jun 2019 11:49:57 -0700 Subject: [PATCH 262/676] Add detailed unknown frame type tests --- CMakeLists.txt | 189 ++++++++----- Makefile | 262 ++++++++++++++---- test/core/bad_client/gen_build_yaml.py | 4 +- test/core/bad_client/tests/unknown_frame.cc | 26 +- .../generated/sources_and_headers.json | 24 +- tools/run_tests/generated/tests.json | 22 +- 6 files changed, 362 insertions(+), 165 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9d2168b8de..72e870024d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -438,17 +438,6 @@ add_dependencies(buildtests_c udp_server_test) endif() add_dependencies(buildtests_c uri_parser_test) add_dependencies(buildtests_c public_headers_must_be_c89) -add_dependencies(buildtests_c badreq_bad_client_test) -add_dependencies(buildtests_c connection_prefix_bad_client_test) -add_dependencies(buildtests_c duplicate_header_bad_client_test) -add_dependencies(buildtests_c head_of_line_blocking_bad_client_test) -add_dependencies(buildtests_c headers_bad_client_test) -add_dependencies(buildtests_c initial_settings_frame_bad_client_test) -add_dependencies(buildtests_c large_metadata_bad_client_test) -add_dependencies(buildtests_c server_registered_method_bad_client_test) -add_dependencies(buildtests_c simple_request_bad_client_test) -add_dependencies(buildtests_c unknown_frame_bad_client_test) -add_dependencies(buildtests_c window_overflow_bad_client_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c bad_ssl_cert_server) endif() @@ -733,6 +722,17 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx writes_per_rpc_test) endif() add_dependencies(buildtests_cxx xds_end2end_test) +add_dependencies(buildtests_cxx badreq_bad_client_test) +add_dependencies(buildtests_cxx connection_prefix_bad_client_test) +add_dependencies(buildtests_cxx duplicate_header_bad_client_test) +add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test) +add_dependencies(buildtests_cxx headers_bad_client_test) +add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test) +add_dependencies(buildtests_cxx large_metadata_bad_client_test) +add_dependencies(buildtests_cxx server_registered_method_bad_client_test) +add_dependencies(buildtests_cxx simple_request_bad_client_test) +add_dependencies(buildtests_cxx unknown_frame_bad_client_test) +add_dependencies(buildtests_cxx window_overflow_bad_client_test) add_dependencies(buildtests_cxx resolver_component_test_unsecure) add_dependencies(buildtests_cxx resolver_component_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -5833,18 +5833,19 @@ target_include_directories(bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(bad_client_test PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() target_link_libraries(bad_client_test + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -17019,6 +17020,8 @@ if (gRPC_BUILD_TESTS) add_executable(badreq_bad_client_test test/core/bad_client/tests/badreq.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17033,28 +17036,32 @@ target_include_directories(badreq_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(badreq_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(badreq_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(badreq_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(connection_prefix_bad_client_test test/core/bad_client/tests/connection_prefix.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17069,28 +17076,32 @@ target_include_directories(connection_prefix_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(connection_prefix_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(connection_prefix_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(connection_prefix_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(duplicate_header_bad_client_test test/core/bad_client/tests/duplicate_header.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17105,28 +17116,32 @@ target_include_directories(duplicate_header_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(duplicate_header_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(duplicate_header_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(duplicate_header_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(head_of_line_blocking_bad_client_test test/core/bad_client/tests/head_of_line_blocking.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17141,28 +17156,32 @@ target_include_directories(head_of_line_blocking_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(head_of_line_blocking_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(head_of_line_blocking_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(head_of_line_blocking_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(headers_bad_client_test test/core/bad_client/tests/headers.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17177,28 +17196,32 @@ target_include_directories(headers_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(headers_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(headers_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(headers_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(initial_settings_frame_bad_client_test test/core/bad_client/tests/initial_settings_frame.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17213,28 +17236,32 @@ target_include_directories(initial_settings_frame_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(initial_settings_frame_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(initial_settings_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(initial_settings_frame_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(large_metadata_bad_client_test test/core/bad_client/tests/large_metadata.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17249,28 +17276,32 @@ target_include_directories(large_metadata_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(large_metadata_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(large_metadata_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(large_metadata_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(server_registered_method_bad_client_test test/core/bad_client/tests/server_registered_method.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17285,28 +17316,32 @@ target_include_directories(server_registered_method_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(server_registered_method_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(server_registered_method_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(server_registered_method_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(simple_request_bad_client_test test/core/bad_client/tests/simple_request.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17321,28 +17356,32 @@ target_include_directories(simple_request_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(simple_request_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(simple_request_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(simple_request_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(unknown_frame_bad_client_test test/core/bad_client/tests/unknown_frame.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17357,28 +17396,32 @@ target_include_directories(unknown_frame_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(unknown_frame_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(unknown_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(unknown_frame_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(window_overflow_bad_client_test test/core/bad_client/tests/window_overflow.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc ) @@ -17393,22 +17436,24 @@ target_include_directories(window_overflow_bad_client_test PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} ) target_link_libraries(window_overflow_bad_client_test ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(window_overflow_bad_client_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(window_overflow_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index e56c5ec4e47..84b40cb9af0 100644 --- a/Makefile +++ b/Makefile @@ -1405,7 +1405,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -1415,9 +1415,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libdns_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a endif @@ -1555,17 +1555,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ - $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ - $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ - $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ - $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \ - $(BINDIR)/$(CONFIG)/headers_bad_client_test \ - $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ - $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ - $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ - $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ - $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ - $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \ $(BINDIR)/$(CONFIG)/bad_ssl_cert_server \ $(BINDIR)/$(CONFIG)/bad_ssl_cert_test \ $(BINDIR)/$(CONFIG)/h2_census_test \ @@ -1762,6 +1751,17 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \ $(BINDIR)/$(CONFIG)/boringssl_crypto_test \ + $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ + $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ + $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ + $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \ + $(BINDIR)/$(CONFIG)/headers_bad_client_test \ + $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ + $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ + $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ + $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ + $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -1910,6 +1910,17 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ + $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ + $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ + $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ + $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \ + $(BINDIR)/$(CONFIG)/headers_bad_client_test \ + $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ + $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ + $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ + $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ + $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -2176,28 +2187,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_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" - $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing connection_prefix_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing duplicate_header_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing head_of_line_blocking_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing headers_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing initial_settings_frame_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing large_metadata_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing server_registered_method_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing simple_request_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/simple_request_bad_client_test || ( echo test simple_request_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing unknown_frame_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing window_overflow_bad_client_test" - $(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing bad_ssl_cert_test" $(Q) $(BINDIR)/$(CONFIG)/bad_ssl_cert_test || ( echo test bad_ssl_cert_test failed ; exit 1 ) @@ -2452,6 +2441,28 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) $(E) "[RUN] Testing xds_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing badreq_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing connection_prefix_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing duplicate_header_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing head_of_line_blocking_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing headers_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing initial_settings_frame_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing large_metadata_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing server_registered_method_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing simple_request_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/simple_request_bad_client_test || ( echo test simple_request_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing unknown_frame_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing window_overflow_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure" $(Q) $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure || ( echo test resolver_component_tests_runner_invoker_unsecure failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker" @@ -8529,7 +8540,7 @@ endif LIBBAD_CLIENT_TEST_SRC = \ test/core/bad_client/bad_client.cc \ -PUBLIC_HEADERS_C += \ +PUBLIC_HEADERS_CXX += \ LIBBAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBAD_CLIENT_TEST_SRC)))) @@ -8543,8 +8554,16 @@ $(LIBDIR)/$(CONFIG)/libbad_client_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)/libbad_client_test.a: protobuf_dep_error + -$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBBAD_CLIENT_TEST_OBJS) +else + +$(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBAD_CLIENT_TEST_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a @@ -8556,6 +8575,8 @@ endif +endif + endif ifneq ($(NO_SECURE),true) @@ -20298,10 +20319,21 @@ BADREQ_BAD_CLIENT_TEST_SRC = \ BADREQ_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BADREQ_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/badreq_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/badreq_bad_client_test: $(PROTOBUF_DEP) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(BADREQ_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/badreq_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/badreq.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20318,10 +20350,21 @@ CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC = \ CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONNECTION_PREFIX_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test: $(PROTOBUF_DEP) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(CONNECTION_PREFIX_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/connection_prefix.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20338,10 +20381,21 @@ DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \ DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(PROTOBUF_DEP) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20358,10 +20412,21 @@ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(PROTOBUF_DEP) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20378,10 +20443,21 @@ HEADERS_BAD_CLIENT_TEST_SRC = \ HEADERS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEADERS_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/headers_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/headers_bad_client_test: $(PROTOBUF_DEP) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(HEADERS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/headers_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/headers.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20398,10 +20474,21 @@ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC = \ INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test: $(PROTOBUF_DEP) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(INITIAL_SETTINGS_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/initial_settings_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20418,10 +20505,21 @@ LARGE_METADATA_BAD_CLIENT_TEST_SRC = \ LARGE_METADATA_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LARGE_METADATA_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/large_metadata_bad_client_test: $(PROTOBUF_DEP) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(LARGE_METADATA_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/large_metadata.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20438,10 +20536,21 @@ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test: $(PROTOBUF_DEP) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/server_registered_method.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20458,10 +20567,21 @@ SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC = \ SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SIMPLE_REQUEST_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/simple_request_bad_client_test: $(PROTOBUF_DEP) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(SIMPLE_REQUEST_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/simple_request_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/simple_request.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20478,10 +20598,21 @@ UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \ UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(PROTOBUF_DEP) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a @@ -20498,10 +20629,21 @@ WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC = \ WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test: $(PROTOBUF_DEP) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test + $(Q) $(LDXX) $(LDFLAGS) $(WINDOW_OVERFLOW_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test + +endif $(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/window_overflow.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 6a40b4e5e9d..bd311ccfd90 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -45,7 +45,7 @@ def main(): { 'name': 'bad_client_test', 'build': 'private', - 'language': 'c', + 'language': 'c++', 'src': [ 'test/core/bad_client/bad_client.cc' ], @@ -64,7 +64,7 @@ def main(): 'name': '%s_bad_client_test' % t, 'cpu_cost': BAD_CLIENT_TESTS[t].cpu_cost, 'build': 'test', - 'language': 'c', + 'language': 'c++', 'secure': 'no', 'src': ['test/core/bad_client/tests/%s.cc' % t], 'vs_proj_dir': 'test', diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc index 9e0cf3f6a90..fa29ace2e35 100644 --- a/test/core/bad_client/tests/unknown_frame.cc +++ b/test/core/bad_client/tests/unknown_frame.cc @@ -16,13 +16,12 @@ * */ +#include + +#include #include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" -#define PFX_STR \ - "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ - "\x00\x00\x00\x04\x00\x00\x00\x00\x00" - static void verifier(grpc_server* server, grpc_completion_queue* cq, void* registered_method) { while (grpc_server_has_open_connections(server)) { @@ -36,10 +35,21 @@ int main(int argc, char** argv) { grpc_init(); grpc::testing::TestEnvironment env(argc, argv); - /* test adding prioritization data */ - GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, - PFX_STR "\x00\x00\x00\x88\x00\x00\x00\x00\x01", - GRPC_BAD_CLIENT_DISCONNECT); + /* test that all invalid/unknown frame types are handled */ + for (int i = 10; i <= 255; i++) { + std::string unknown_frame_string; + unknown_frame_string.append("\x01\x01\x01", sizeof("\x00\x00\x00") - 1); + char frame_type = static_cast(i); + unknown_frame_string.append(&frame_type, 1); + unknown_frame_string.append("\x01\x02\x03\x04\x05", + sizeof("\x00\x00\x00\x00\x01") - 1); + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = nullptr; + args[1].client_payload = unknown_frame_string.c_str(); + args[1].client_payload_length = unknown_frame_string.size(); + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); + } grpc_shutdown(); return 0; diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a479a00509a..6e31e5fdd30 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5276,7 +5276,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "badreq_bad_client_test", "src": [ "test/core/bad_client/tests/badreq.cc" @@ -5293,7 +5293,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "connection_prefix_bad_client_test", "src": [ "test/core/bad_client/tests/connection_prefix.cc" @@ -5310,7 +5310,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "duplicate_header_bad_client_test", "src": [ "test/core/bad_client/tests/duplicate_header.cc" @@ -5327,7 +5327,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "head_of_line_blocking_bad_client_test", "src": [ "test/core/bad_client/tests/head_of_line_blocking.cc" @@ -5344,7 +5344,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "headers_bad_client_test", "src": [ "test/core/bad_client/tests/headers.cc" @@ -5361,7 +5361,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "initial_settings_frame_bad_client_test", "src": [ "test/core/bad_client/tests/initial_settings_frame.cc" @@ -5378,7 +5378,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "large_metadata_bad_client_test", "src": [ "test/core/bad_client/tests/large_metadata.cc" @@ -5395,7 +5395,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "server_registered_method_bad_client_test", "src": [ "test/core/bad_client/tests/server_registered_method.cc" @@ -5412,7 +5412,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "simple_request_bad_client_test", "src": [ "test/core/bad_client/tests/simple_request.cc" @@ -5429,7 +5429,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "unknown_frame_bad_client_test", "src": [ "test/core/bad_client/tests/unknown_frame.cc" @@ -5446,7 +5446,7 @@ ], "headers": [], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "window_overflow_bad_client_test", "src": [ "test/core/bad_client/tests/window_overflow.cc" @@ -7740,7 +7740,7 @@ "test/core/bad_client/bad_client.h" ], "is_filegroup": false, - "language": "c", + "language": "c++", "name": "bad_client_test", "src": [ "test/core/bad_client/bad_client.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 473e2e26c3a..37a69a47b23 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5934,7 +5934,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "badreq_bad_client_test", "platforms": [ "linux", @@ -5960,7 +5960,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "connection_prefix_bad_client_test", "platforms": [ "linux", @@ -5986,7 +5986,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "duplicate_header_bad_client_test", "platforms": [ "linux", @@ -6012,7 +6012,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "head_of_line_blocking_bad_client_test", "platforms": [ "linux", @@ -6038,7 +6038,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "headers_bad_client_test", "platforms": [ "linux", @@ -6064,7 +6064,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "initial_settings_frame_bad_client_test", "platforms": [ "linux", @@ -6090,7 +6090,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "large_metadata_bad_client_test", "platforms": [ "linux", @@ -6116,7 +6116,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "server_registered_method_bad_client_test", "platforms": [ "linux", @@ -6142,7 +6142,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "simple_request_bad_client_test", "platforms": [ "linux", @@ -6168,7 +6168,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "unknown_frame_bad_client_test", "platforms": [ "linux", @@ -6194,7 +6194,7 @@ ], "flaky": false, "gtest": false, - "language": "c", + "language": "c++", "name": "window_overflow_bad_client_test", "platforms": [ "linux", From cd848e17f21e547bef8895946756520fc2794dda Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 6 Jun 2019 12:58:34 -0700 Subject: [PATCH 263/676] Bump up the Cython version to 0.29.8 --- requirements.bazel.txt | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.bazel.txt b/requirements.bazel.txt index e2618c950f3..4d52beb9e11 100644 --- a/requirements.bazel.txt +++ b/requirements.bazel.txt @@ -1,6 +1,6 @@ # GRPC Python setup requirements coverage>=4.0 -cython>=0.28.3 +cython>=0.29.8 enum34>=1.0.4 protobuf>=3.5.0.post1 six>=1.10 diff --git a/requirements.txt b/requirements.txt index f583fc94eb4..27dd7d9f63b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ # GRPC Python setup requirements coverage>=4.0 -cython>=0.28.3 +cython>=0.29.8 enum34>=1.0.4 protobuf>=3.5.0.post1 six>=1.10 From d30d538dbab5fd5f19edad59dd6282e515bb85a3 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 6 Jun 2019 13:56:46 -0700 Subject: [PATCH 264/676] Move math_server.js out of examples/ directory --- src/php/README.md | 4 ++-- .../php/tests/generated_code}/math_server.js | 2 +- src/php/tests/generated_code/package.json | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) rename {examples/node/dynamic_codegen => src/php/tests/generated_code}/math_server.js (97%) create mode 100644 src/php/tests/generated_code/package.json diff --git a/src/php/README.md b/src/php/README.md index 69f4bbf42c2..dde6152cfce 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -294,9 +294,9 @@ Run a local server serving the math services. Please see [Node][] for how to run an example server. ```sh -$ cd grpc/examples/node +$ cd grpc/src/php/tests/generated_code $ npm install -$ node dynamic_codegen/math_server.js +$ node math_server.js ``` ### Run test client diff --git a/examples/node/dynamic_codegen/math_server.js b/src/php/tests/generated_code/math_server.js similarity index 97% rename from examples/node/dynamic_codegen/math_server.js rename to src/php/tests/generated_code/math_server.js index d4eb310fc88..1492c936e13 100644 --- a/examples/node/dynamic_codegen/math_server.js +++ b/src/php/tests/generated_code/math_server.js @@ -16,7 +16,7 @@ * */ -var PROTO_PATH = __dirname + '/../../../src/proto/math/math.proto'; +var PROTO_PATH = __dirname + '/../../../proto/math/math.proto'; var grpc = require('grpc'); var protoLoader = require('@grpc/proto-loader'); diff --git a/src/php/tests/generated_code/package.json b/src/php/tests/generated_code/package.json new file mode 100644 index 00000000000..318ef4fd01f --- /dev/null +++ b/src/php/tests/generated_code/package.json @@ -0,0 +1,11 @@ +{ + "name": "grpc-examples", + "version": "0.1.0", + "dependencies": { + "@grpc/proto-loader": "^0.1.0", + "async": "^1.5.2", + "grpc": "^1.11.0", + "lodash": "^4.6.1", + "minimist": "^1.2.0" + } +} From 3b61d3efa3f3d3b4b4e9f4feed45a3e859fc827a Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 6 Jun 2019 14:05:08 -0700 Subject: [PATCH 265/676] Further simplify package.json --- src/php/tests/generated_code/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/php/tests/generated_code/package.json b/src/php/tests/generated_code/package.json index 318ef4fd01f..5cc28be35d2 100644 --- a/src/php/tests/generated_code/package.json +++ b/src/php/tests/generated_code/package.json @@ -3,9 +3,6 @@ "version": "0.1.0", "dependencies": { "@grpc/proto-loader": "^0.1.0", - "async": "^1.5.2", - "grpc": "^1.11.0", - "lodash": "^4.6.1", - "minimist": "^1.2.0" + "grpc": "^1.11.0" } } From 46e3df3dead7d5f26094c65323ff19eb18859d93 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Jun 2019 07:22:24 -0400 Subject: [PATCH 266/676] php interop client: construct channel target like other languages do --- src/php/tests/interop/interop_client.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 19cbf21bc2b..e4750475dc5 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -530,12 +530,7 @@ function _makeStub($args) throw new Exception('Missing argument: --test_case is required'); } - if ($args['server_port'] === '443') { - $server_address = $args['server_host']; - } else { - $server_address = $args['server_host'].':'.$args['server_port']; - } - + $server_address = $args['server_host'].':'.$args['server_port']; $test_case = $args['test_case']; $host_override = ''; From 3b742f1fabdc6d09ecf81ebd5b527b1b49dac57f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Jun 2019 10:27:59 -0400 Subject: [PATCH 267/676] remove port suffix from JWT audience --- src/php/lib/Grpc/BaseStub.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index fe81e377610..1d2c30341dd 100644 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -199,6 +199,13 @@ class BaseStub */ private function _get_jwt_aud_uri($method) { + // TODO(jtattermusch): This is not the correct implementation + // of extracting JWT "aud" claim. We should rely on + // grpc_metadata_credentials_plugin which + // also provides the correct value of "aud" claim + // in the grpc_auth_metadata_context.service_url field. + // Trying to do the construction of "aud" field ourselves + // is bad. $last_slash_idx = strrpos($method, '/'); if ($last_slash_idx === false) { throw new \InvalidArgumentException( @@ -213,6 +220,12 @@ class BaseStub $hostname = $this->hostname; } + // Remove the port if it is 443 + // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/lib/security/transport/client_auth_filter.cc#L205 + if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) { + $hostname = substr($hostname, 0, -4); + } + return 'https://'.$hostname.$service_name; } From 195aae6cb5c56dd119b358586c44c5569529aa63 Mon Sep 17 00:00:00 2001 From: Lily Li Date: Thu, 6 Jun 2019 16:34:48 -0700 Subject: [PATCH 268/676] add compatibility check badge to README --- src/python/grpcio/README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst index 07c94342de1..c7c6aa497d5 100644 --- a/src/python/grpcio/README.rst +++ b/src/python/grpcio/README.rst @@ -1,8 +1,13 @@ gRPC Python =========== +|compat_check_pypi| + Package for gRPC Python. +.. |compat_check_pypi| image:: https://python-compatibility-tools.appspot.com/one_badge_image?package=grpcio + :target: https://python-compatibility-tools.appspot.com/one_badge_target?package=grpcio + Supported Python Versions ------------------------- Python >= 3.5 From 597a67a2b57364d7e8336fe1cccb2ae03cec25b8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 6 Jun 2019 18:18:30 -0700 Subject: [PATCH 269/676] Covert to GTEST --- test/core/bad_client/generate_tests.bzl | 4 ++++ test/core/bad_client/tests/unknown_frame.cc | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 2769d5c3bb6..9ff55877c53 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -42,6 +42,10 @@ def grpc_bad_client_tests(): name = 'bad_client_test', srcs = ['bad_client.cc'], hdrs = ['bad_client.h'], + external_deps = [ + "gtest", + ], + language = "C++", deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier'] ) for t, topt in BAD_CLIENT_TESTS.items(): diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc index fa29ace2e35..a9f56548c2a 100644 --- a/test/core/bad_client/tests/unknown_frame.cc +++ b/test/core/bad_client/tests/unknown_frame.cc @@ -18,6 +18,8 @@ #include +#include + #include #include "src/core/lib/surface/server.h" #include "test/core/bad_client/bad_client.h" @@ -31,17 +33,15 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } } -int main(int argc, char** argv) { - grpc_init(); - grpc::testing::TestEnvironment env(argc, argv); - +namespace { +TEST(UnknownFrameType, Test) { /* test that all invalid/unknown frame types are handled */ for (int i = 10; i <= 255; i++) { std::string unknown_frame_string; - unknown_frame_string.append("\x01\x01\x01", sizeof("\x00\x00\x00") - 1); + unknown_frame_string.append("\x00\x00\x00", sizeof("\x00\x00\x00") - 1); char frame_type = static_cast(i); unknown_frame_string.append(&frame_type, 1); - unknown_frame_string.append("\x01\x02\x03\x04\x05", + unknown_frame_string.append("\x00\x00\x00\x00\x01", sizeof("\x00\x00\x00\x00\x01") - 1); grpc_bad_client_arg args[2]; args[0] = connection_preface_arg; @@ -50,7 +50,14 @@ int main(int argc, char** argv) { args[1].client_payload_length = unknown_frame_string.size(); grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); } +} +} // namespace +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); grpc_shutdown(); - return 0; + return retval; } From b015b437bb279e8ea4d469fed49b6c9d70276bd6 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 6 Jun 2019 22:59:49 -0700 Subject: [PATCH 270/676] Bump version to v1.21.4-pre1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index af1d7847cef..894516243e4 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.3" +version = "1.21.4-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index d9a72738f48..0d3ce2406bb 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.3 + version: 1.21.4-pre1 filegroups: - name: alts_proto headers: From 40a914e8466c621283570037a7fd9cbc0dd634d2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Thu, 6 Jun 2019 23:00:48 -0700 Subject: [PATCH 271/676] Re-generate projects; --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f01e790264..0bb9b9312b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.3") +set(PACKAGE_VERSION "1.21.4-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index fd29aa3fc73..ec7f34dc57a 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.3 -CSHARP_VERSION = 1.21.3 +CPP_VERSION = 1.21.4-pre1 +CSHARP_VERSION = 1.21.4-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1fdd6423a7e..5e65031a6f4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.3' - version = '0.0.9' + # version = '1.21.4-pre1' + version = '0.0.9-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.3' + grpc_version = '1.21.4-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 061d3a27504..901d91173a8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.3' + version = '1.21.4-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index c38719b7d52..9c1bb7881be 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.3' + version = '1.21.4-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 20f93164969..0b7ba325e35 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.3' + version = '1.21.4-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index e268a8b21aa..5b57e7270f3 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.3' + version = '1.21.4-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index f03c4e694d8..8f528b8f721 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.3 - 1.21.3 + 1.21.4RC1 + 1.21.4RC1 - stable - stable + beta + beta Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 98c1ba34470..6fb5d2f23be 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.3"; } +grpc::string Version() { return "1.21.4-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index 3d4bdd9ee78..d7a68c43ffc 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.21.3.0"; + public const string CurrentAssemblyFileVersion = "1.21.4.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.3"; + public const string CurrentVersion = "1.21.4-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index 949b683ccb5..bcab16551ff 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.3 + 1.21.4-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index a371568fab8..6852a761d6a 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.3 +set VERSION=1.21.4-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index c4b588824de..cf558c97c13 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.3' + v = '1.21.4-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 20cf2ac4811..b5385b26a43 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.3" +#define GRPC_OBJC_VERSION_STRING @"1.21.4-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 0aa72ca70da..38cf3d9585c 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.3" +#define GRPC_OBJC_VERSION_STRING @"1.21.4-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 48dfde56d86..1369fd34bc6 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.21.3", + "version": "1.21.4", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index d401a7d2095..78e627e70f0 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.3" +#define PHP_GRPC_VERSION "1.21.4RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index ea4600f7d0a..b54340e02e4 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.3""" +__version__ = """1.21.4rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index ad12bf478ed..ef2cab7665f 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 73ecfb1c3c7..9a3b2997b40 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c26d3697972..a3fe3a2bed5 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index b434ba9422e..f835fd96941 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 4516db48837..e6825a4545c 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 735c66a9081..fa200e63a13 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index ab2507f2c94..f3e90cef876 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 55b26e434a6..987be56d824 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.3' + VERSION = '1.21.4.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 4effc70d476..e53b605d1fb 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.3' + VERSION = '1.21.4.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index bb7110142ae..ff2dc093b0a 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.3' +VERSION = '1.21.4rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 15f82e95211..d6a55647d75 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.3 +PROJECT_NUMBER = 1.21.4-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 63614418486..ce404fca6dd 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.3 +PROJECT_NUMBER = 1.21.4-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From e8800dc1dce557c0f83e08027a3d72af0cfceef3 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 7 Jun 2019 01:29:01 -0700 Subject: [PATCH 272/676] Bump to version v1.21.4 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index 894516243e4..534c203dc3d 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gandalf" core_version = "7.0.0" -version = "1.21.4-pre1" +version = "1.21.4" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 0d3ce2406bb..03d0275cc9c 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gandalf - version: 1.21.4-pre1 + version: 1.21.4 filegroups: - name: alts_proto headers: From 795e31a84bdf30d4dfe40dd5aa1ec71587ca172b Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 7 Jun 2019 01:29:45 -0700 Subject: [PATCH 273/676] Re-generate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bb9b9312b2..6c936b1f5db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.21.4-pre1") +set(PACKAGE_VERSION "1.21.4") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index ec7f34dc57a..2dbb86a679f 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.21.4-pre1 -CSHARP_VERSION = 1.21.4-pre1 +CPP_VERSION = 1.21.4 +CSHARP_VERSION = 1.21.4 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5e65031a6f4..2be3fdf9fdd 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.21.4-pre1' - version = '0.0.9-pre1' + # version = '1.21.4' + version = '0.0.9' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.21.4-pre1' + grpc_version = '1.21.4' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 901d91173a8..46715bc8715 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.21.4-pre1' + version = '1.21.4' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 9c1bb7881be..49004350d28 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.21.4-pre1' + version = '1.21.4' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 0b7ba325e35..ea440649c72 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.21.4-pre1' + version = '1.21.4' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 5b57e7270f3..1901d00c372 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.21.4-pre1' + version = '1.21.4' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 8f528b8f721..6a7a49929b1 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.21.4RC1 - 1.21.4RC1 + 1.21.4 + 1.21.4 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 6fb5d2f23be..cc238901a74 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.21.4-pre1"; } +grpc::string Version() { return "1.21.4"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index d7a68c43ffc..3c6d92354bf 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.21.4-pre1"; + public const string CurrentVersion = "1.21.4"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index bcab16551ff..a51f6f9acca 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.21.4-pre1 + 1.21.4 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 6852a761d6a..214db46b787 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.21.4-pre1 +set VERSION=1.21.4 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index cf558c97c13..9aba47a3c67 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.21.4-pre1' + v = '1.21.4' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index b5385b26a43..87791c04498 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.4-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.4" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 38cf3d9585c..8f1b5c75983 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.21.4-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.21.4" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 78e627e70f0..2ec4cd814a6 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.21.4RC1" +#define PHP_GRPC_VERSION "1.21.4" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index b54340e02e4..8f794a197e9 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.21.4rc1""" +__version__ = """1.21.4""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index ef2cab7665f..e31c9ba513a 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 9a3b2997b40..1c80bec0ab2 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index a3fe3a2bed5..20fd62b19a1 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index f835fd96941..7d0b5feb9b2 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index e6825a4545c..8cfbf946b07 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index fa200e63a13..73f1e1484c5 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index f3e90cef876..2497489a049 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 987be56d824..46dfae0919e 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.21.4.pre1' + VERSION = '1.21.4' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index e53b605d1fb..697e166eada 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.21.4.pre1' + VERSION = '1.21.4' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index ff2dc093b0a..4b72433b70f 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.21.4rc1' +VERSION = '1.21.4' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index d6a55647d75..b99ee5e30d2 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.4-pre1 +PROJECT_NUMBER = 1.21.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ce404fca6dd..00e9cad77f4 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.21.4-pre1 +PROJECT_NUMBER = 1.21.4 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From cfb31818ef40c401dd50bd4a20492ff2812472d3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 7 Jun 2019 07:09:39 -0700 Subject: [PATCH 274/676] Remove channelz from LB policy API. --- .../filters/client_channel/client_channel.cc | 105 +++++++---- .../filters/client_channel/client_channel.h | 8 - .../client_channel/client_channel_channelz.cc | 83 --------- .../client_channel/client_channel_channelz.h | 30 +--- .../client_channel/client_channel_plugin.cc | 8 - .../ext/filters/client_channel/lb_policy.h | 28 +-- .../client_channel/lb_policy/grpclb/grpclb.cc | 101 ++++------- .../lb_policy/pick_first/pick_first.cc | 59 ------ .../lb_policy/round_robin/round_robin.cc | 58 ------ .../lb_policy/subchannel_list.h | 13 -- .../client_channel/lb_policy/xds/xds.cc | 170 ++++++------------ .../client_channel/resolving_lb_policy.cc | 83 +++------ .../client_channel/resolving_lb_policy.h | 8 - .../client_channel/subchannel_interface.h | 10 +- src/core/lib/channel/channelz.cc | 155 ++++++++++++++-- src/core/lib/channel/channelz.h | 76 ++++---- src/core/lib/surface/channel.cc | 133 +++++++++----- src/core/lib/surface/channel.h | 4 +- test/core/channel/channel_trace_test.cc | 11 +- test/core/channel/channelz_test.cc | 3 +- test/core/util/test_lb_policies.cc | 10 +- test/cpp/end2end/channelz_service_test.cc | 3 +- 22 files changed, 466 insertions(+), 693 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 6b6045c98f6..81562ab2107 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -118,18 +118,6 @@ class ChannelData { static void GetChannelInfo(grpc_channel_element* elem, const grpc_channel_info* info); - void set_channelz_node(channelz::ClientChannelNode* node) { - channelz_node_ = node; - resolving_lb_policy_->set_channelz_node(node->Ref()); - } - void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - if (resolving_lb_policy_ != nullptr) { - resolving_lb_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } - } - bool deadline_checking_enabled() const { return deadline_checking_enabled_; } bool enable_retries() const { return enable_retries_; } size_t per_rpc_retry_buffer_size() const { @@ -249,8 +237,7 @@ class ChannelData { ClientChannelFactory* client_channel_factory_; UniquePtr server_name_; RefCountedPtr default_service_config_; - // Initialized shortly after construction. - channelz::ClientChannelNode* channelz_node_ = nullptr; + channelz::ChannelNode* channelz_node_; // // Fields used in the data plane. Guarded by data_plane_combiner. @@ -269,12 +256,13 @@ class ChannelData { grpc_combiner* combiner_; grpc_pollset_set* interested_parties_; RefCountedPtr subchannel_pool_; - OrphanablePtr resolving_lb_policy_; + OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; bool received_first_resolver_result_ = false; + Map subchannel_refcount_map_; // // Fields accessed from both data plane and control plane combiners. @@ -735,6 +723,7 @@ class ChannelData::ConnectivityStateAndPickerSetter { // Update connectivity state here, while holding control plane combiner. grpc_connectivity_state_set(&chand->state_tracker_, state, reason); if (chand->channelz_node_ != nullptr) { + chand->channelz_node_->SetConnectivityState(state); chand->channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string( @@ -971,12 +960,39 @@ void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( // control plane combiner. class ChannelData::GrpcSubchannel : public SubchannelInterface { public: - GrpcSubchannel(Subchannel* subchannel, + GrpcSubchannel(ChannelData* chand, Subchannel* subchannel, UniquePtr health_check_service_name) - : subchannel_(subchannel), - health_check_service_name_(std::move(health_check_service_name)) {} + : chand_(chand), + subchannel_(subchannel), + health_check_service_name_(std::move(health_check_service_name)) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "GrpcSubchannel"); + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + if (it == chand_->subchannel_refcount_map_.end()) { + chand_->channelz_node_->AddChildSubchannel(subchannel_uuid); + it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first; + } + ++it->second; + } + } - ~GrpcSubchannel() { GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); } + ~GrpcSubchannel() { + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + GPR_ASSERT(it != chand_->subchannel_refcount_map_.end()); + --it->second; + if (it->second == 0) { + chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid); + chand_->subchannel_refcount_map_.erase(it); + } + } + GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "GrpcSubchannel"); + } grpc_connectivity_state CheckConnectivityState( RefCountedPtr* connected_subchannel) @@ -1005,13 +1021,10 @@ class ChannelData::GrpcSubchannel : public SubchannelInterface { void AttemptToConnect() override { subchannel_->AttemptToConnect(); } - channelz::SubchannelNode* channelz_node() override { - return subchannel_->channelz_node(); - } - void ResetBackoff() override { subchannel_->ResetBackoff(); } private: + ChannelData* chand_; Subchannel* subchannel_; UniquePtr health_check_service_name_; }; @@ -1041,7 +1054,10 @@ class ChannelData::ClientChannelControlHelper health_check_service_name.reset( gpr_strdup(chand_->health_check_service_name_.get())); } - static const char* args_to_remove[] = {GRPC_ARG_INHIBIT_HEALTH_CHECKING}; + static const char* args_to_remove[] = { + GRPC_ARG_INHIBIT_HEALTH_CHECKING, + GRPC_ARG_CHANNELZ_CHANNEL_NODE, + }; grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( @@ -1050,7 +1066,7 @@ class ChannelData::ClientChannelControlHelper chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) return nullptr; - return MakeRefCounted(subchannel, + return MakeRefCounted(chand_, subchannel, std::move(health_check_service_name)); } @@ -1082,7 +1098,22 @@ class ChannelData::ClientChannelControlHelper // No-op -- we should never get this from ResolvingLoadBalancingPolicy. void RequestReresolution() override {} + void AddTraceEvent(TraceSeverity severity, const char* message) override { + if (chand_->channelz_node_ != nullptr) { + chand_->channelz_node_->AddTraceEvent( + ConvertSeverityEnum(severity), + grpc_slice_from_copied_string(message)); + } + } + private: + static channelz::ChannelTrace::Severity ConvertSeverityEnum( + TraceSeverity severity) { + if (severity == TRACE_INFO) return channelz::ChannelTrace::Info; + if (severity == TRACE_WARNING) return channelz::ChannelTrace::Warning; + return channelz::ChannelTrace::Error; + } + ChannelData* chand_; }; @@ -1125,6 +1156,15 @@ RefCountedPtr GetSubchannelPool( return GlobalSubchannelPool::instance(); } +channelz::ChannelNode* GetChannelzNode(const grpc_channel_args* args) { + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_CHANNELZ_CHANNEL_NODE); + if (arg != nullptr && arg->type == GRPC_ARG_POINTER) { + return static_cast(arg->value.pointer.p); + } + return nullptr; +} + ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) : deadline_checking_enabled_( grpc_deadline_checking_enabled(args->channel_args)), @@ -1134,6 +1174,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) owning_stack_(args->channel_stack), client_channel_factory_( ClientChannelFactory::GetFromChannelArgs(args->channel_args)), + channelz_node_(GetChannelzNode(args->channel_args)), data_plane_combiner_(grpc_combiner_create()), combiner_(grpc_combiner_create()), interested_parties_(grpc_pollset_set_create()), @@ -3532,20 +3573,6 @@ const grpc_channel_filter grpc_client_channel_filter = { "client-channel", }; -void grpc_client_channel_set_channelz_node( - grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { - auto* chand = static_cast(elem->channel_data); - chand->set_channelz_node(node); -} - -void grpc_client_channel_populate_child_refs( - grpc_channel_element* elem, - grpc_core::channelz::ChildRefsList* child_subchannels, - grpc_core::channelz::ChildRefsList* child_channels) { - auto* chand = static_cast(elem->channel_data); - chand->FillChildRefsForChannelz(child_subchannels, child_channels); -} - grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { auto* chand = static_cast(elem->channel_data); diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h index 5bfff4df9cd..caaa079dd9b 100644 --- a/src/core/ext/filters/client_channel/client_channel.h +++ b/src/core/ext/filters/client_channel/client_channel.h @@ -40,14 +40,6 @@ extern grpc_core::TraceFlag grpc_client_channel_trace; extern const grpc_channel_filter grpc_client_channel_filter; -void grpc_client_channel_set_channelz_node( - grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node); - -void grpc_client_channel_populate_child_refs( - grpc_channel_element* elem, - grpc_core::channelz::ChildRefsList* child_subchannels, - grpc_core::channelz::ChildRefsList* child_channels); - grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index de61819ef54..e068d11dc41 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -29,89 +29,6 @@ namespace grpc_core { namespace channelz { -namespace { - -void* client_channel_channelz_copy(void* p) { return p; } - -void client_channel_channelz_destroy(void* p) {} - -int client_channel_channelz_cmp(void* a, void* b) { return GPR_ICMP(a, b); } - -} // namespace - -static const grpc_arg_pointer_vtable client_channel_channelz_vtable = { - client_channel_channelz_copy, client_channel_channelz_destroy, - client_channel_channelz_cmp}; - -ClientChannelNode::ClientChannelNode(grpc_channel* channel, - size_t channel_tracer_max_nodes, - bool is_top_level_channel) - : ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) { - client_channel_ = - grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); - GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter); - grpc_client_channel_set_channelz_node(client_channel_, this); -} - -void ClientChannelNode::PopulateConnectivityState(grpc_json* json) { - grpc_connectivity_state state; - if (ChannelIsDestroyed()) { - state = GRPC_CHANNEL_SHUTDOWN; - } else { - state = - grpc_client_channel_check_connectivity_state(client_channel_, false); - } - json = grpc_json_create_child(nullptr, json, "state", nullptr, - GRPC_JSON_OBJECT, false); - grpc_json_create_child(nullptr, json, "state", - grpc_connectivity_state_name(state), GRPC_JSON_STRING, - false); -} - -void ClientChannelNode::PopulateChildRefs(grpc_json* json) { - ChildRefsList child_subchannels; - ChildRefsList child_channels; - grpc_json* json_iterator = nullptr; - grpc_client_channel_populate_child_refs(client_channel_, &child_subchannels, - &child_channels); - if (!child_subchannels.empty()) { - grpc_json* array_parent = grpc_json_create_child( - nullptr, json, "subchannelRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < child_subchannels.size(); ++i) { - json_iterator = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); - grpc_json_add_number_string_child(json_iterator, nullptr, "subchannelId", - child_subchannels[i]); - } - } - if (!child_channels.empty()) { - grpc_json* array_parent = grpc_json_create_child( - nullptr, json, "channelRef", nullptr, GRPC_JSON_ARRAY, false); - json_iterator = nullptr; - for (size_t i = 0; i < child_channels.size(); ++i) { - json_iterator = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); - grpc_json_add_number_string_child(json_iterator, nullptr, "channelId", - child_channels[i]); - } - } -} - -grpc_arg ClientChannelNode::CreateChannelArg() { - return grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC), - reinterpret_cast(MakeClientChannelNode), - &client_channel_channelz_vtable); -} - -RefCountedPtr ClientChannelNode::MakeClientChannelNode( - grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel) { - return MakeRefCounted(channel, channel_tracer_max_nodes, - is_top_level_channel); -} SubchannelNode::SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 9272116882e..9f11e928998 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -32,32 +32,6 @@ class Subchannel; namespace channelz { -// Subtype of ChannelNode that overrides and provides client_channel specific -// functionality like querying for connectivity_state and subchannel data. -class ClientChannelNode : public ChannelNode { - public: - static RefCountedPtr MakeClientChannelNode( - grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); - - ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); - virtual ~ClientChannelNode() {} - - // Overriding template methods from ChannelNode to render information that - // only ClientChannelNode knows about. - void PopulateConnectivityState(grpc_json* json) override; - void PopulateChildRefs(grpc_json* json) override; - - // Helper to create a channel arg to ensure this type of ChannelNode is - // created. - static grpc_arg CreateChannelArg(); - - private: - grpc_channel_element* client_channel_; -}; - -// Handles channelz bookkeeping for sockets class SubchannelNode : public BaseNode { public: SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); @@ -85,12 +59,12 @@ class SubchannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: + void PopulateConnectivityState(grpc_json* json); + Subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; - - void PopulateConnectivityState(grpc_json* json); }; } // namespace channelz diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 3a7492d82d9..c5662e22a20 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -38,14 +38,6 @@ #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { - const grpc_channel_args* args = - grpc_channel_stack_builder_get_channel_arguments(builder); - grpc_arg args_to_add[] = { - grpc_core::channelz::ClientChannelNode::CreateChannelArg()}; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add( - args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); - grpc_channel_stack_builder_set_channel_arguments(builder, new_args); - grpc_channel_args_destroy(new_args); return grpc_channel_stack_builder_append_filter( builder, static_cast(arg), nullptr, nullptr); } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 2cadcc31998..d508932015d 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -21,7 +21,6 @@ #include -#include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel_interface.h" @@ -31,6 +30,7 @@ #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" namespace grpc_core { @@ -201,6 +201,12 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Requests that the resolver re-resolve. virtual void RequestReresolution() GRPC_ABSTRACT; + /// Adds a trace message associated with the channel. + /// Does NOT take ownership of \a message. + enum TraceSeverity { TRACE_INFO, TRACE_WARNING, TRACE_ERROR }; + virtual void AddTraceEvent(TraceSeverity severity, + const char* message) GRPC_ABSTRACT; + GRPC_ABSTRACT_BASE_CLASS }; @@ -274,20 +280,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Resets connection backoff. virtual void ResetBackoffLocked() GRPC_ABSTRACT; - /// Populates child_subchannels and child_channels with the uuids of this - /// LB policy's referenced children. - /// - /// This is not invoked from the client_channel's combiner. The - /// implementation is responsible for providing its own synchronization. - virtual void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) GRPC_ABSTRACT; - - void set_channelz_node( - RefCountedPtr channelz_node) { - channelz_node_ = std::move(channelz_node); - } - grpc_pollset_set* interested_parties() const { return interested_parties_; } void Orphan() override; @@ -333,10 +325,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { return channel_control_helper_.get(); } - channelz::ClientChannelNode* channelz_node() const { - return channelz_node_.get(); - } - /// Shuts down the policy. virtual void ShutdownLocked() GRPC_ABSTRACT; @@ -349,8 +337,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties_; /// Channel control helper. UniquePtr channel_control_helper_; - /// Channelz node. - RefCountedPtr channelz_node_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a3a2a44eb0e..a87dfda7321 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -141,9 +141,6 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override; private: /// Contains a call to the LB server and all the data related to the call. @@ -300,6 +297,7 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateState(grpc_connectivity_state state, UniquePtr picker) override; void RequestReresolution() override; + void AddTraceEvent(TraceSeverity severity, const char* message) override; void set_child(LoadBalancingPolicy* child) { child_ = child; } @@ -349,8 +347,6 @@ class GrpcLb : public LoadBalancingPolicy { // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; - // Uuid of the lb channel. Used for channelz. - gpr_atm lb_channel_uuid_ = 0; // Response generator to inject address updates into lb_channel_. RefCountedPtr response_generator_; @@ -386,9 +382,6 @@ class GrpcLb : public LoadBalancingPolicy { grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE; grpc_closure lb_channel_on_connectivity_changed_; - // Lock held when modifying the value of child_policy_ or - // pending_child_policy_. - gpr_mu child_policy_mu_; // The child policy to use for the backends. OrphanablePtr child_policy_; // When switching child policies, the new policy will be stored here @@ -655,7 +648,6 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, grpc_pollset_set_del_pollset_set( parent_->child_policy_->interested_parties(), parent_->interested_parties()); - MutexLock lock(&parent_->child_policy_mu_); parent_->child_policy_ = std::move(parent_->pending_child_policy_); } else if (!CalledByCurrentChild()) { // This request is from an outdated child, so ignore it. @@ -735,6 +727,15 @@ void GrpcLb::Helper::RequestReresolution() { } } +void GrpcLb::Helper::AddTraceEvent(TraceSeverity severity, + const char* message) { + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return; + } + parent_->channel_control_helper()->AddTraceEvent(severity, message); +} + // // GrpcLb::BalancerCallState // @@ -1244,25 +1245,34 @@ grpc_channel_args* BuildBalancerChannelArgs( // treated as a stand-alone channel and not inherit this argument from the // args of the parent channel. GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + // Don't want to pass down channelz node from parent; the balancer + // channel will get its own. + GRPC_ARG_CHANNELZ_CHANNEL_NODE, }; // Channel args to add. - const grpc_arg args_to_add[] = { - // The fake resolver response generator, which we use to inject - // address updates into the LB channel. + InlinedVector args_to_add; + // The fake resolver response generator, which we use to inject + // address updates into the LB channel. + args_to_add.emplace_back( grpc_core::FakeResolverResponseGenerator::MakeChannelArg( - response_generator), - // A channel arg indicating the target is a grpclb load balancer. - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), 1), - // A channel arg indicating this is an internal channels, aka it is - // owned by components in Core, not by the user application. - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL), 1), - }; + response_generator)); + // A channel arg indicating the target is a grpclb load balancer. + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), 1)); + // The parent channel's channelz uuid. + channelz::ChannelNode* channelz_node = nullptr; + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_CHANNELZ_CHANNEL_NODE); + if (arg != nullptr && arg->type == GRPC_ARG_POINTER && + arg->value.pointer.p != nullptr) { + channelz_node = static_cast(arg->value.pointer.p); + args_to_add.emplace_back( + channelz::MakeParentUuidArg(channelz_node->uuid())); + } // Construct channel args. grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( - args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add.data(), + args_to_add.size()); // Make any necessary modifications for security. return grpc_lb_policy_grpclb_modify_lb_channel_args(addresses, new_args); } @@ -1288,7 +1298,6 @@ GrpcLb::GrpcLb(Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - gpr_mu_init(&child_policy_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1314,7 +1323,6 @@ GrpcLb::GrpcLb(Args args) GrpcLb::~GrpcLb() { gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - gpr_mu_destroy(&child_policy_mu_); } void GrpcLb::ShutdownLocked() { @@ -1335,11 +1343,8 @@ void GrpcLb::ShutdownLocked() { grpc_pollset_set_del_pollset_set( pending_child_policy_->interested_parties(), interested_parties()); } - { - MutexLock lock(&child_policy_mu_); - child_policy_.reset(); - pending_child_policy_.reset(); - } + child_policy_.reset(); + pending_child_policy_.reset(); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1347,7 +1352,6 @@ void GrpcLb::ShutdownLocked() { if (lb_channel_ != nullptr) { grpc_channel_destroy(lb_channel_); lb_channel_ = nullptr; - gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } } @@ -1367,29 +1371,6 @@ void GrpcLb::ResetBackoffLocked() { } } -void GrpcLb::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - { - // Delegate to the child policy to fill the children subchannels. - // This must be done holding child_policy_mu_, since this method - // does not run in the combiner. - MutexLock lock(&child_policy_mu_); - if (child_policy_ != nullptr) { - child_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } - if (pending_child_policy_ != nullptr) { - pending_child_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } - } - gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); - if (uuid != 0) { - child_channels->push_back(uuid); - } -} - void GrpcLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_channel_ == nullptr; auto* grpclb_config = @@ -1472,11 +1453,6 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked( lb_channel_ = channel_control_helper()->CreateChannel(uri_str, *lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); - if (channel_node != nullptr) { - gpr_atm_no_barrier_store(&lb_channel_uuid_, channel_node->uuid()); - } gpr_free(uri_str); } // Propagate updates to the LB channel (pick_first) through the fake @@ -1764,15 +1740,10 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - auto new_policy = - CreateChildPolicyLocked(child_policy_name, update_args.args); // Swap the policy into place. auto& lb_policy = child_policy_ == nullptr ? child_policy_ : pending_child_policy_; - { - MutexLock lock(&child_policy_mu_); - lb_policy = std::move(new_policy); - } + lb_policy = CreateChildPolicyLocked(child_policy_name, update_args.args); policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 4680117fede..e4b58eb7558 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -53,8 +53,6 @@ class PickFirst : public LoadBalancingPolicy { void UpdateLocked(UpdateArgs args) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; - void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* ignored) override; private: ~PickFirst(); @@ -128,22 +126,8 @@ class PickFirst : public LoadBalancingPolicy { RefCountedPtr connected_subchannel_; }; - // Helper class to ensure that any function that modifies the child refs - // data structures will update the channelz snapshot data structures before - // returning. - class AutoChildRefsUpdater { - public: - explicit AutoChildRefsUpdater(PickFirst* pf) : pf_(pf) {} - ~AutoChildRefsUpdater() { pf_->UpdateChildRefsLocked(); } - - private: - PickFirst* pf_; - }; - void ShutdownLocked() override; - void UpdateChildRefsLocked(); - // All our subchannels. OrphanablePtr subchannel_list_; // Latest pending subchannel list. @@ -154,12 +138,6 @@ class PickFirst : public LoadBalancingPolicy { bool idle_ = false; // Are we shut down? bool shutdown_ = false; - - /// Lock and data used to capture snapshots of this channels child - /// channels and subchannels. This data is consumed by channelz. - Mutex child_refs_mu_; - channelz::ChildRefsList child_subchannels_; - channelz::ChildRefsList child_channels_; }; PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { @@ -177,7 +155,6 @@ PickFirst::~PickFirst() { } void PickFirst::ShutdownLocked() { - AutoChildRefsUpdater guard(this); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p Shutting down", this); } @@ -212,42 +189,7 @@ void PickFirst::ResetBackoffLocked() { } } -void PickFirst::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels_to_fill, - channelz::ChildRefsList* ignored) { - MutexLock lock(&child_refs_mu_); - for (size_t i = 0; i < child_subchannels_.size(); ++i) { - // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might - // have to implement lightweight set. For now, we don't care about - // performance when channelz requests are made. - bool found = false; - for (size_t j = 0; j < child_subchannels_to_fill->size(); ++j) { - if ((*child_subchannels_to_fill)[j] == child_subchannels_[i]) { - found = true; - break; - } - } - if (!found) { - child_subchannels_to_fill->push_back(child_subchannels_[i]); - } - } -} - -void PickFirst::UpdateChildRefsLocked() { - channelz::ChildRefsList cs; - if (subchannel_list_ != nullptr) { - subchannel_list_->PopulateChildRefsList(&cs); - } - if (latest_pending_subchannel_list_ != nullptr) { - latest_pending_subchannel_list_->PopulateChildRefsList(&cs); - } - // atomically update the data that channelz will actually be looking at. - MutexLock lock(&child_refs_mu_); - child_subchannels_ = std::move(cs); -} - void PickFirst::UpdateLocked(UpdateArgs args) { - AutoChildRefsUpdater guard(this); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, @@ -348,7 +290,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) { void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state) { PickFirst* p = static_cast(subchannel_list()->policy()); - AutoChildRefsUpdater guard(p); // The notification must be for a subchannel in either the current or // latest pending subchannel lists. GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() || diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 3b8ec4f2872..17c65d8b551 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -63,8 +63,6 @@ class RoundRobin : public LoadBalancingPolicy { void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; - void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* ignored) override; private: ~RoundRobin(); @@ -160,22 +158,8 @@ class RoundRobin : public LoadBalancingPolicy { InlinedVector, 10> subchannels_; }; - // Helper class to ensure that any function that modifies the child refs - // data structures will update the channelz snapshot data structures before - // returning. - class AutoChildRefsUpdater { - public: - explicit AutoChildRefsUpdater(RoundRobin* rr) : rr_(rr) {} - ~AutoChildRefsUpdater() { rr_->UpdateChildRefsLocked(); } - - private: - RoundRobin* rr_; - }; - void ShutdownLocked() override; - void UpdateChildRefsLocked(); - /** list of subchannels */ OrphanablePtr subchannel_list_; /** Latest version of the subchannel list. @@ -186,11 +170,6 @@ class RoundRobin : public LoadBalancingPolicy { OrphanablePtr latest_pending_subchannel_list_; /** are we shutting down? */ bool shutdown_ = false; - /// Lock and data used to capture snapshots of this channel's child - /// channels and subchannels. This data is consumed by channelz. - Mutex child_refs_mu_; - channelz::ChildRefsList child_subchannels_; - channelz::ChildRefsList child_channels_; }; // @@ -255,7 +234,6 @@ RoundRobin::~RoundRobin() { } void RoundRobin::ShutdownLocked() { - AutoChildRefsUpdater guard(this); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } @@ -271,40 +249,6 @@ void RoundRobin::ResetBackoffLocked() { } } -void RoundRobin::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels_to_fill, - channelz::ChildRefsList* ignored) { - MutexLock lock(&child_refs_mu_); - for (size_t i = 0; i < child_subchannels_.size(); ++i) { - // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might - // have to implement lightweight set. For now, we don't care about - // performance when channelz requests are made. - bool found = false; - for (size_t j = 0; j < child_subchannels_to_fill->size(); ++j) { - if ((*child_subchannels_to_fill)[j] == child_subchannels_[i]) { - found = true; - break; - } - } - if (!found) { - child_subchannels_to_fill->push_back(child_subchannels_[i]); - } - } -} - -void RoundRobin::UpdateChildRefsLocked() { - channelz::ChildRefsList cs; - if (subchannel_list_ != nullptr) { - subchannel_list_->PopulateChildRefsList(&cs); - } - if (latest_pending_subchannel_list_ != nullptr) { - latest_pending_subchannel_list_->PopulateChildRefsList(&cs); - } - // atomically update the data that channelz will actually be looking at. - MutexLock lock(&child_refs_mu_); - child_subchannels_ = std::move(cs); -} - void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { if (num_subchannels() == 0) return; // Check current state of each subchannel synchronously, since any @@ -396,7 +340,6 @@ void RoundRobin::RoundRobinSubchannelList:: void RoundRobin::RoundRobinSubchannelList:: UpdateRoundRobinStateFromSubchannelStateCountsLocked() { RoundRobin* p = static_cast(policy()); - AutoChildRefsUpdater guard(p); if (num_ready_ > 0) { if (p->subchannel_list_.get() != this) { // Promote this list to p->subchannel_list_. @@ -468,7 +411,6 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( } void RoundRobin::UpdateLocked(UpdateArgs args) { - AutoChildRefsUpdater guard(this); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", this, args.addresses.size()); diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 8929bc4ab1e..7d70928a83c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -223,19 +223,6 @@ class SubchannelList : public InternallyRefCounted { // Returns true if the subchannel list is shutting down. bool shutting_down() const { return shutting_down_; } - // Populates refs_list with the uuids of this SubchannelLists's subchannels. - void PopulateChildRefsList(channelz::ChildRefsList* refs_list) { - for (size_t i = 0; i < subchannels_.size(); ++i) { - if (subchannels_[i].subchannel() != nullptr) { - grpc_core::channelz::SubchannelNode* subchannel_node = - subchannels_[i].subchannel()->channelz_node(); - if (subchannel_node != nullptr) { - refs_list->push_back(subchannel_node->uuid()); - } - } - } - } - // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 041c1e46231..136d85bba14 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -157,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override; private: struct LocalityServerlistEntry; @@ -343,6 +340,7 @@ class XdsLb : public LoadBalancingPolicy { void UpdateState(grpc_connectivity_state state, UniquePtr picker) override; void RequestReresolution() override; + void AddTraceEvent(TraceSeverity severity, const char* message) override; void set_child(LoadBalancingPolicy* child) { child_ = child; } @@ -398,8 +396,6 @@ class XdsLb : public LoadBalancingPolicy { const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); - void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels); void Orphan() override; private: @@ -415,6 +411,8 @@ class XdsLb : public LoadBalancingPolicy { void UpdateState(grpc_connectivity_state state, UniquePtr picker) override; void RequestReresolution() override; + void AddTraceEvent(TraceSeverity severity, + const char* message) override; void set_child(LoadBalancingPolicy* child) { child_ = child; } private: @@ -432,9 +430,6 @@ class XdsLb : public LoadBalancingPolicy { OrphanablePtr child_policy_; OrphanablePtr pending_child_policy_; - // Lock held when modifying the value of child_policy_ or - // pending_child_policy_. - Mutex child_policy_mu_; RefCountedPtr parent_; RefCountedPtr picker_ref_; grpc_connectivity_state connectivity_state_; @@ -446,17 +441,12 @@ class XdsLb : public LoadBalancingPolicy { const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); - void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels); private: void PruneLocalities(const LocalityList& locality_list); Map, OrphanablePtr, LocalityName::Less> map_; - // Lock held while filling child refs for all localities - // inside the map - Mutex child_refs_mu_; }; struct LocalityServerlistEntry { @@ -511,10 +501,6 @@ class XdsLb : public LoadBalancingPolicy { // The channel for communicating with the LB server. OrphanablePtr lb_chand_; OrphanablePtr pending_lb_chand_; - // Mutex to protect the channel to the LB server. This is used when - // processing a channelz request. - // TODO(juanlishen): Replace this with atomic. - Mutex lb_chand_mu_; // Timeout in milliseconds for the LB call. 0 means no deadline. int lb_call_timeout_ms_ = 0; @@ -538,9 +524,6 @@ class XdsLb : public LoadBalancingPolicy { // The policy to use for the fallback backends. RefCountedPtr fallback_policy_config_; - // Lock held when modifying the value of fallback_policy_ or - // pending_fallback_policy_. - Mutex fallback_policy_mu_; // Non-null iff we are in fallback mode. OrphanablePtr fallback_policy_; OrphanablePtr pending_fallback_policy_; @@ -648,7 +631,6 @@ void XdsLb::FallbackHelper::UpdateState(grpc_connectivity_state state, grpc_pollset_set_del_pollset_set( parent_->fallback_policy_->interested_parties(), parent_->interested_parties()); - MutexLock lock(&parent_->fallback_policy_mu_); parent_->fallback_policy_ = std::move(parent_->pending_fallback_policy_); } else if (!CalledByCurrentFallback()) { // This request is from an outdated fallback policy, so ignore it. @@ -673,6 +655,15 @@ void XdsLb::FallbackHelper::RequestReresolution() { parent_->channel_control_helper()->RequestReresolution(); } +void XdsLb::FallbackHelper::AddTraceEvent(TraceSeverity severity, + const char* message) { + if (parent_->shutting_down_ || + (!CalledByPendingFallback() && !CalledByCurrentFallback())) { + return; + } + parent_->channel_control_helper()->AddTraceEvent(severity, message); +} + // // serverlist parsing code // @@ -1365,21 +1356,29 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) { // treated as a stand-alone channel and not inherit this argument from the // args of the parent channel. GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + // Don't want to pass down channelz node from parent; the balancer + // channel will get its own. + GRPC_ARG_CHANNELZ_CHANNEL_NODE, }; // Channel args to add. - const grpc_arg args_to_add[] = { - // A channel arg indicating the target is a xds load balancer. - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1), - // A channel arg indicating this is an internal channels, aka it is - // owned by components in Core, not by the user application. - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL), 1), - }; + InlinedVector args_to_add; + // A channel arg indicating the target is a xds load balancer. + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1)); + // The parent channel's channelz uuid. + channelz::ChannelNode* channelz_node = nullptr; + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_CHANNELZ_CHANNEL_NODE); + if (arg != nullptr && arg->type == GRPC_ARG_POINTER && + arg->value.pointer.p != nullptr) { + channelz_node = static_cast(arg->value.pointer.p); + args_to_add.emplace_back( + channelz::MakeParentUuidArg(channelz_node->uuid())); + } // Construct channel args. grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( - args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add.data(), + args_to_add.size()); // Make any necessary modifications for security. return grpc_lb_policy_xds_modify_lb_channel_args(new_args); } @@ -1434,18 +1433,12 @@ void XdsLb::ShutdownLocked() { grpc_pollset_set_del_pollset_set( pending_fallback_policy_->interested_parties(), interested_parties()); } - { - MutexLock lock(&fallback_policy_mu_); - fallback_policy_.reset(); - pending_fallback_policy_.reset(); - } + fallback_policy_.reset(); + pending_fallback_policy_.reset(); // We reset the LB channels here instead of in our destructor because they // hold refs to XdsLb. - { - MutexLock lock(&lb_chand_mu_); - lb_chand_.reset(); - pending_lb_chand_.reset(); - } + lb_chand_.reset(); + pending_lb_chand_.reset(); } // @@ -1468,40 +1461,6 @@ void XdsLb::ResetBackoffLocked() { } } -void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - // Delegate to the locality_map_ to fill the children subchannels. - locality_map_.FillChildRefsForChannelz(child_subchannels, child_channels); - { - // This must be done holding fallback_policy_mu_, since this method does not - // run in the combiner. - MutexLock lock(&fallback_policy_mu_); - if (fallback_policy_ != nullptr) { - fallback_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } - if (pending_fallback_policy_ != nullptr) { - pending_fallback_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } - } - MutexLock lock(&lb_chand_mu_); - if (lb_chand_ != nullptr) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_chand_->channel()); - if (channel_node != nullptr) { - child_channels->push_back(channel_node->uuid()); - } - } - if (pending_lb_chand_ != nullptr) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(pending_lb_chand_->channel()); - if (channel_node != nullptr) { - child_channels->push_back(channel_node->uuid()); - } - } -} - void XdsLb::ProcessAddressesAndChannelArgsLocked( const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. @@ -1691,14 +1650,10 @@ void XdsLb::UpdateFallbackPolicyLocked() { fallback_policy_ == nullptr ? "" : "pending ", fallback_policy_name); } - auto new_policy = - CreateFallbackPolicyLocked(fallback_policy_name, update_args.args); auto& lb_policy = fallback_policy_ == nullptr ? fallback_policy_ : pending_fallback_policy_; - { - MutexLock lock(&fallback_policy_mu_); - lb_policy = std::move(new_policy); - } + lb_policy = + CreateFallbackPolicyLocked(fallback_policy_name, update_args.args); policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. @@ -1769,7 +1724,6 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { } } if (!found) { // Remove entries not present in the locality list - MutexLock lock(&child_refs_mu_); iter = map_.erase(iter); } else iter++; @@ -1786,7 +1740,6 @@ void XdsLb::LocalityMap::UpdateLocked( if (iter == map_.end()) { OrphanablePtr new_entry = MakeOrphanable( parent->Ref(), locality_serverlist[i]->locality_weight); - MutexLock lock(&child_refs_mu_); iter = map_.emplace(locality_serverlist[i]->locality_name, std::move(new_entry)) .first; @@ -1799,10 +1752,7 @@ void XdsLb::LocalityMap::UpdateLocked( PruneLocalities(locality_serverlist); } -void XdsLb::LocalityMap::ShutdownLocked() { - MutexLock lock(&child_refs_mu_); - map_.clear(); -} +void XdsLb::LocalityMap::ShutdownLocked() { map_.clear(); } void XdsLb::LocalityMap::ResetBackoffLocked() { for (auto& p : map_) { @@ -1810,15 +1760,6 @@ void XdsLb::LocalityMap::ResetBackoffLocked() { } } -void XdsLb::LocalityMap::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - MutexLock lock(&child_refs_mu_); - for (auto& p : map_) { - p.second->FillChildRefsForChannelz(child_subchannels, child_channels); - } -} - // // XdsLb::LocalityMap::LocalityEntry // @@ -1954,14 +1895,9 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - auto new_policy = - CreateChildPolicyLocked(child_policy_name, update_args.args); auto& lb_policy = child_policy_ == nullptr ? child_policy_ : pending_child_policy_; - { - MutexLock lock(&child_policy_mu_); - lb_policy = std::move(new_policy); - } + lb_policy = CreateChildPolicyLocked(child_policy_name, update_args.args); policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. @@ -1991,11 +1927,8 @@ void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { pending_child_policy_->interested_parties(), parent_->interested_parties()); } - { - MutexLock lock(&child_policy_mu_); - child_policy_.reset(); - pending_child_policy_.reset(); - } + child_policy_.reset(); + pending_child_policy_.reset(); } void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { @@ -2005,17 +1938,6 @@ void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { } } -void XdsLb::LocalityMap::LocalityEntry::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - MutexLock lock(&child_policy_mu_); - child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - if (pending_child_policy_ != nullptr) { - pending_child_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } -} - void XdsLb::LocalityMap::LocalityEntry::Orphan() { ShutdownLocked(); Unref(); @@ -2070,7 +1992,6 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( grpc_pollset_set_del_pollset_set( entry_->child_policy_->interested_parties(), entry_->parent_->interested_parties()); - MutexLock lock(&entry_->child_policy_mu_); entry_->child_policy_ = std::move(entry_->pending_child_policy_); } else if (!CalledByCurrentChild()) { // This request is from an outdated child, so ignore it. @@ -2180,6 +2101,15 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { } } +void XdsLb::LocalityMap::LocalityEntry::Helper::AddTraceEvent( + TraceSeverity severity, const char* message) { + if (entry_->parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return; + } + entry_->parent_->channel_control_helper()->AddTraceEvent(severity, message); +} + // // factory // diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index d23ac1f4e33..180b0fcbbf4 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -137,7 +137,6 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper grpc_pollset_set_del_pollset_set( parent_->lb_policy_->interested_parties(), parent_->interested_parties()); - MutexLock lock(&parent_->lb_policy_mu_); parent_->lb_policy_ = std::move(parent_->pending_lb_policy_); } else if (!CalledByCurrentChild()) { // This request is from an outdated child, so ignore it. @@ -214,7 +213,6 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( process_resolver_result_(process_resolver_result), process_resolver_result_user_data_(process_resolver_result_user_data) { GPR_ASSERT(process_resolver_result != nullptr); - gpr_mu_init(&lb_policy_mu_); *error = Init(*args.args); } @@ -234,13 +232,11 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { GPR_ASSERT(resolver_ == nullptr); GPR_ASSERT(lb_policy_ == nullptr); - gpr_mu_destroy(&lb_policy_mu_); } void ResolvingLoadBalancingPolicy::ShutdownLocked() { if (resolver_ != nullptr) { resolver_.reset(); - MutexLock lock(&lb_policy_mu_); if (lb_policy_ != nullptr) { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, @@ -282,22 +278,6 @@ void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { if (pending_lb_policy_ != nullptr) pending_lb_policy_->ResetBackoffLocked(); } -void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - // Delegate to the lb_policy_ to fill the children subchannels. - // This must be done holding lb_policy_mu_, since this method does not - // run in the combiner. - MutexLock lock(&lb_policy_mu_); - if (lb_policy_ != nullptr) { - lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - if (pending_lb_policy_ != nullptr) { - pending_lb_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); - } -} - void ResolvingLoadBalancingPolicy::StartResolvingLocked() { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); @@ -403,13 +383,9 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this, lb_policy_ == nullptr ? "" : "pending ", lb_policy_name); } - auto new_policy = - CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings); auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_; - { - MutexLock lock(&lb_policy_mu_); - lb_policy = std::move(new_policy); - } + lb_policy = + CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings); policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. @@ -451,11 +427,9 @@ ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( lb_policy_name, std::move(lb_policy_args)); if (GPR_UNLIKELY(lb_policy == nullptr)) { gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (channelz_node() != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); - trace_strings->push_back(str); - } + char* str; + gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); return nullptr; } helper->set_child(lb_policy.get()); @@ -463,16 +437,9 @@ ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", this, lb_policy_name, lb_policy.get()); } - if (channelz_node() != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); - trace_strings->push_back(str); - } - // Propagate channelz node. - auto* channelz = channelz_node(); - if (channelz != nullptr) { - lb_policy->set_channelz_node(channelz->Ref()); - } + char* str; + gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), interested_parties()); return lb_policy; @@ -502,11 +469,10 @@ void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( is_first = false; gpr_strvec_add(&v, (*trace_strings)[i]); } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node()->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); + size_t len = 0; + UniquePtr message(gpr_strvec_flatten(&v, &len)); + channel_control_helper()->AddTraceEvent(ChannelControlHelper::TRACE_INFO, + message.get()); gpr_strvec_destroy(&v); } } @@ -560,21 +526,18 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( std::move(result), &trace_strings); } // Add channel trace event. - if (channelz_node() != nullptr) { - if (service_config_changed) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - if (service_config_error_string != nullptr) { - trace_strings.push_back(service_config_error_string); - service_config_error_string = nullptr; - } - MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses, - &trace_strings); - ConcatenateAndAddChannelTraceLocked(&trace_strings); + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + if (service_config_error_string != nullptr) { + trace_strings.push_back(service_config_error_string); + service_config_error_string = nullptr; } - gpr_free(service_config_error_string); + MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses, + &trace_strings); + ConcatenateAndAddChannelTraceLocked(&trace_strings); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 679c8d0fba0..e91ea832661 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -21,7 +21,6 @@ #include -#include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/lb_policy.h" #include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" @@ -91,10 +90,6 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void ResetBackoffLocked() override; - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override; - private: using TraceStringVector = InlinedVector; @@ -137,9 +132,6 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Child LB policy. OrphanablePtr lb_policy_; OrphanablePtr pending_lb_policy_; - // Lock held when modifying the value of child_policy_ or - // pending_child_policy_. - gpr_mu lb_policy_mu_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel_interface.h b/src/core/ext/filters/client_channel/subchannel_interface.h index 0a471045f03..10b1bf124c2 100644 --- a/src/core/ext/filters/client_channel/subchannel_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_interface.h @@ -94,11 +94,15 @@ class SubchannelInterface : public RefCounted { GRPC_ABSTRACT; // Attempt to connect to the backend. Has no effect if already connected. + // If the subchannel is currently in backoff delay due to a previously + // failed attempt, the new connection attempt will not start until the + // backoff delay has elapsed. virtual void AttemptToConnect() GRPC_ABSTRACT; - // TODO(roth): These methods should be removed from this interface to - // bettter hide grpc-specific functionality from the LB policy API. - virtual channelz::SubchannelNode* channelz_node() GRPC_ABSTRACT; + // Resets the subchannel's connection backoff state. If AttemptToConnect() + // has been called since the subchannel entered TRANSIENT_FAILURE state, + // starts a new connection attempt immediately; otherwise, a new connection + // attempt will be started as soon as AttemptToConnect() is called. virtual void ResetBackoff() GRPC_ABSTRACT; GRPC_ABSTRACT_BASE_CLASS diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 0eed9a59fef..4b130372e46 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -40,12 +40,51 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" +#include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/uri/uri_parser.h" namespace grpc_core { namespace channelz { +// +// channel arg code +// + +namespace { + +void* parent_uuid_copy(void* p) { return p; } +void parent_uuid_destroy(void* p) {} +int parent_uuid_cmp(void* p1, void* p2) { return GPR_ICMP(p1, p2); } +const grpc_arg_pointer_vtable parent_uuid_vtable = { + parent_uuid_copy, parent_uuid_destroy, parent_uuid_cmp}; + +} // namespace + +grpc_arg MakeParentUuidArg(intptr_t parent_uuid) { + // We would ideally like to store the uuid in an integer argument. + // Unfortunately, that won't work, because intptr_t (the type used for + // uuids) doesn't fit in an int (the type used for integer args). + // So instead, we use a hack to store it as a pointer, because + // intptr_t should be the same size as void*. + static_assert(sizeof(intptr_t) <= sizeof(void*), + "can't fit intptr_t inside of void*"); + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_CHANNELZ_PARENT_UUID), + reinterpret_cast(parent_uuid), &parent_uuid_vtable); +} + +intptr_t GetParentUuidFromArgs(const grpc_channel_args& args) { + const grpc_arg* arg = + grpc_channel_args_find(&args, GRPC_ARG_CHANNELZ_PARENT_UUID); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return 0; + return reinterpret_cast(arg->value.pointer.p); +} + +// +// BaseNode +// + BaseNode::BaseNode(EntityType type) : type_(type), uuid_(-1) { // The registry will set uuid_ under its lock. ChannelzRegistry::Register(this); @@ -61,6 +100,10 @@ char* BaseNode::RenderJsonString() { return json_str; } +// +// CallCountingHelper +// + CallCountingHelper::CallCountingHelper() { num_cores_ = GPR_MAX(1, gpr_cpu_num_cores()); per_cpu_counter_data_storage_ = static_cast( @@ -137,15 +180,17 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) { } } -ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel) - : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel - : EntityType::kInternalChannel), - channel_(channel), - target_(UniquePtr(grpc_channel_get_target(channel_))), - trace_(channel_tracer_max_nodes) {} +// +// ChannelNode +// -ChannelNode::~ChannelNode() {} +ChannelNode::ChannelNode(UniquePtr target, + size_t channel_tracer_max_nodes, intptr_t parent_uuid) + : BaseNode(parent_uuid == 0 ? EntityType::kTopLevelChannel + : EntityType::kInternalChannel), + target_(std::move(target)), + trace_(channel_tracer_max_nodes), + parent_uuid_(parent_uuid) {} grpc_json* ChannelNode::RenderJson() { // We need to track these three json objects to build our object @@ -167,9 +212,19 @@ grpc_json* ChannelNode::RenderJson() { GRPC_JSON_OBJECT, false); json = data; json_iterator = nullptr; - // template method. Child classes may override this to add their specific - // functionality. - PopulateConnectivityState(json); + // connectivity state + // If low-order bit is on, then the field is set. + int state_field = connectivity_state_.Load(MemoryOrder::RELAXED); + if ((state_field & 1) != 0) { + grpc_connectivity_state state = + static_cast(state_field >> 1); + json = grpc_json_create_child(nullptr, json, "state", nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_create_child(nullptr, json, "state", + grpc_connectivity_state_name(state), + GRPC_JSON_STRING, false); + json = data; + } // populate the target. GPR_ASSERT(target_.get() != nullptr); grpc_json_create_child(nullptr, json, "target", target_.get(), @@ -189,13 +244,64 @@ grpc_json* ChannelNode::RenderJson() { return top_level_json; } -RefCountedPtr ChannelNode::MakeChannelNode( - grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel) { - return MakeRefCounted( - channel, channel_tracer_max_nodes, is_top_level_channel); +void ChannelNode::PopulateChildRefs(grpc_json* json) { + MutexLock lock(&child_mu_); + grpc_json* json_iterator = nullptr; + if (!child_subchannels_.empty()) { + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "subchannelRef", nullptr, GRPC_JSON_ARRAY, false); + for (const auto& p : child_subchannels_) { + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "subchannelId", + p.first); + } + } + if (!child_channels_.empty()) { + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "channelRef", nullptr, GRPC_JSON_ARRAY, false); + json_iterator = nullptr; + for (const auto& p : child_channels_) { + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "channelId", + p.first); + } + } +} + +void ChannelNode::SetConnectivityState(grpc_connectivity_state state) { + // Store with low-order bit set to indicate that the field is set. + int state_field = (state << 1) + 1; + connectivity_state_.Store(state_field, MemoryOrder::RELAXED); +} + +void ChannelNode::AddChildChannel(intptr_t child_uuid) { + MutexLock lock(&child_mu_); + child_channels_.insert(MakePair(child_uuid, true)); +} + +void ChannelNode::RemoveChildChannel(intptr_t child_uuid) { + MutexLock lock(&child_mu_); + child_channels_.erase(child_uuid); } +void ChannelNode::AddChildSubchannel(intptr_t child_uuid) { + MutexLock lock(&child_mu_); + child_subchannels_.insert(MakePair(child_uuid, true)); +} + +void ChannelNode::RemoveChildSubchannel(intptr_t child_uuid) { + MutexLock lock(&child_mu_); + child_subchannels_.erase(child_uuid); +} + +// +// ServerNode +// + ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kServer), server_(server), @@ -281,8 +387,14 @@ grpc_json* ServerNode::RenderJson() { return top_level_json; } -static void PopulateSocketAddressJson(grpc_json* json, const char* name, - const char* addr_str) { +// +// SocketNode +// + +namespace { + +void PopulateSocketAddressJson(grpc_json* json, const char* name, + const char* addr_str) { if (addr_str == nullptr) return; grpc_json* json_iterator = nullptr; json_iterator = grpc_json_create_child(json_iterator, json, name, nullptr, @@ -312,7 +424,6 @@ static void PopulateSocketAddressJson(grpc_json* json, const char* name, b64_host, GRPC_JSON_STRING, true); gpr_free(host); gpr_free(port); - } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) { json_iterator = grpc_json_create_child(json_iterator, json, "uds_address", nullptr, GRPC_JSON_OBJECT, false); @@ -332,6 +443,8 @@ static void PopulateSocketAddressJson(grpc_json* json, const char* name, grpc_uri_destroy(uri); } +} // namespace + SocketNode::SocketNode(UniquePtr local, UniquePtr remote) : BaseNode(EntityType::kSocket), local_(std::move(local)), @@ -448,6 +561,10 @@ grpc_json* SocketNode::RenderJson() { return top_level_json; } +// +// ListenSocketNode +// + ListenSocketNode::ListenSocketNode(UniquePtr local_addr) : BaseNode(EntityType::kSocket), local_addr_(std::move(local_addr)) {} diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index e543cda1c2b..f8acb531e8a 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -26,19 +26,19 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/json/json.h" -// Channel arg key for client channel factory. -#define GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC \ - "grpc.channelz_channel_node_creation_func" +// Channel arg key for channelz node. +#define GRPC_ARG_CHANNELZ_CHANNEL_NODE "grpc.channelz_channel_node" -// Channel arg key to signal that the channel is an internal channel. -#define GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL \ - "grpc.channelz_channel_is_internal_channel" +// Channel arg key to encode the channelz uuid of the channel's parent. +#define GRPC_ARG_CHANNELZ_PARENT_UUID "grpc.channelz_parent_uuid" /** This is the default value for whether or not to enable channelz. If * GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */ @@ -54,6 +54,10 @@ namespace grpc_core { namespace channelz { +// Helpers for getting and setting GRPC_ARG_CHANNELZ_PARENT_UUID. +grpc_arg MakeParentUuidArg(intptr_t parent_uuid); +intptr_t GetParentUuidFromArgs(const grpc_channel_args& args); + // TODO(ncteisen), this only contains the uuids of the children for now, // since that is all that is strictly needed. In a future enhancement we will // add human readable names as in the channelz.proto @@ -147,38 +151,13 @@ class CallCountingHelper { // Handles channelz bookkeeping for channels class ChannelNode : public BaseNode { public: - static RefCountedPtr MakeChannelNode( - grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); + ChannelNode(UniquePtr target, size_t channel_tracer_max_nodes, + intptr_t parent_uuid); - ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); - ~ChannelNode() override; + intptr_t parent_uuid() const { return parent_uuid_; } grpc_json* RenderJson() override; - // template methods. RenderJSON uses these methods to render its JSON - // representation. These are virtual so that children classes may provide - // their specific mechanism for populating these parts of the channelz - // object. - // - // ChannelNode does not have a notion of connectivity state or child refs, - // so it leaves these implementations blank. - // - // This is utilizing the template method design pattern. - // - // TODO(ncteisen): remove these template methods in favor of manual traversal - // and mutation of the grpc_json object. - virtual void PopulateConnectivityState(grpc_json* json) {} - virtual void PopulateChildRefs(grpc_json* json) {} - - void MarkChannelDestroyed() { - GPR_ASSERT(channel_ != nullptr); - channel_ = nullptr; - } - - bool ChannelIsDestroyed() { return channel_ == nullptr; } - // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); @@ -193,13 +172,35 @@ class ChannelNode : public BaseNode { void RecordCallFailed() { call_counter_.RecordCallFailed(); } void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } + void SetConnectivityState(grpc_connectivity_state state); + + void AddChildChannel(intptr_t child_uuid); + void RemoveChildChannel(intptr_t child_uuid); + + void AddChildSubchannel(intptr_t child_uuid); + void RemoveChildSubchannel(intptr_t child_uuid); + private: + void PopulateChildRefs(grpc_json* json); + // to allow the channel trace test to access trace_. friend class testing::ChannelNodePeer; - grpc_channel* channel_ = nullptr; + UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; + const intptr_t parent_uuid_; + + // Least significant bit indicates whether the value is set. Remaining + // bits are a grpc_connectivity_state value. + Atomic connectivity_state_{0}; + + Mutex child_mu_; // Guards child maps below. + // TODO(roth): We don't actually use the values here, only the keys, so + // these should be sets instead of maps, but we don't currently have a set + // implementation. Change this if/when we have one. + Map child_channels_; + Map child_subchannels_; }; // Handles channelz bookkeeping for servers @@ -285,11 +286,6 @@ class ListenSocketNode : public BaseNode { UniquePtr local_addr_; }; -// Creation functions - -typedef RefCountedPtr (*ChannelNodeCreationFunc)(grpc_channel*, - size_t, bool); - } // namespace channelz } // namespace grpc_core diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 12869b7780d..e61550743b7 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -33,6 +33,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" +#include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" @@ -86,18 +87,9 @@ grpc_channel* grpc_channel_create_with_builder( grpc_channel_args_destroy(args); return channel; } - channel->target = target; channel->resource_user = resource_user; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); - bool channelz_enabled = GRPC_ENABLE_CHANNELZ_DEFAULT; - size_t channel_tracer_max_memory = - GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT; - bool internal_channel = false; - // this creates the default ChannelNode. Different types of channels may - // override this to ensure a correct ChannelNode is created. - grpc_core::channelz::ChannelNodeCreationFunc channel_node_create_func = - grpc_core::channelz::ChannelNode::MakeChannelNode; gpr_mu_init(&channel->registered_call_mu); channel->registered_calls = nullptr; @@ -129,40 +121,16 @@ grpc_channel* grpc_channel_create_with_builder( channel->compression_options.enabled_algorithms_bitset = static_cast(args->args[i].value.integer) | 0x1; /* always support no compression */ - } else if (0 == strcmp(args->args[i].key, - GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE)) { - const grpc_integer_options options = { - GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}; - channel_tracer_max_memory = - (size_t)grpc_channel_arg_get_integer(&args->args[i], options); - } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) { - // channelz will not be enabled by default until all concerns in - // https://github.com/grpc/grpc/issues/15986 are addressed. - channelz_enabled = grpc_channel_arg_get_bool( - &args->args[i], GRPC_ENABLE_CHANNELZ_DEFAULT); - } else if (0 == strcmp(args->args[i].key, - GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC)) { + } else if (0 == strcmp(args->args[i].key, GRPC_ARG_CHANNELZ_CHANNEL_NODE)) { GPR_ASSERT(args->args[i].type == GRPC_ARG_POINTER); GPR_ASSERT(args->args[i].value.pointer.p != nullptr); - channel_node_create_func = - reinterpret_cast( - args->args[i].value.pointer.p); - } else if (0 == strcmp(args->args[i].key, - GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL)) { - internal_channel = grpc_channel_arg_get_bool(&args->args[i], false); + channel->channelz_node = static_cast( + args->args[i].value.pointer.p) + ->Ref(); } } grpc_channel_args_destroy(args); - // we only need to do the channelz bookkeeping for clients here. The channelz - // bookkeeping for server channels occurs in src/core/lib/surface/server.cc - if (channelz_enabled && channel->is_client) { - channel->channelz_channel = channel_node_create_func( - channel, channel_tracer_max_memory, !internal_channel); - channel->channelz_channel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Channel created")); - } return channel; } @@ -197,6 +165,71 @@ static grpc_channel_args* build_channel_args( return grpc_channel_args_copy_and_add(input_args, new_args, num_new_args); } +namespace { + +void* channelz_node_copy(void* p) { + grpc_core::channelz::ChannelNode* node = + static_cast(p); + node->Ref().release(); + return p; +} +void channelz_node_destroy(void* p) { + grpc_core::channelz::ChannelNode* node = + static_cast(p); + node->Unref(); +} +int channelz_node_cmp(void* p1, void* p2) { return GPR_ICMP(p1, p2); } +const grpc_arg_pointer_vtable channelz_node_arg_vtable = { + channelz_node_copy, channelz_node_destroy, channelz_node_cmp}; + +void CreateChannelzNode(grpc_channel_stack_builder* builder) { + const grpc_channel_args* args = + grpc_channel_stack_builder_get_channel_arguments(builder); + // Check whether channelz is enabled. + const bool channelz_enabled = grpc_channel_arg_get_bool( + grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ), + GRPC_ENABLE_CHANNELZ_DEFAULT); + if (!channelz_enabled) return; + // Get parameters needed to create the channelz node. + const size_t channel_tracer_max_memory = grpc_channel_arg_get_integer( + grpc_channel_args_find(args, + GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + {GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}); + const intptr_t channelz_parent_uuid = + grpc_core::channelz::GetParentUuidFromArgs(*args); + // Create the channelz node. + grpc_core::RefCountedPtr channelz_node = + grpc_core::MakeRefCounted( + grpc_core::UniquePtr( + gpr_strdup(grpc_channel_stack_builder_get_target(builder))), + channel_tracer_max_memory, channelz_parent_uuid); + channelz_node->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Channel created")); + // Update parent channel node, if any. + if (channelz_parent_uuid > 0) { + grpc_core::RefCountedPtr parent_node = + grpc_core::channelz::ChannelzRegistry::Get(channelz_parent_uuid); + if (parent_node != nullptr) { + grpc_core::channelz::ChannelNode* parent = + static_cast(parent_node.get()); + parent->AddChildChannel(channelz_node->uuid()); + } + } + // Add channelz node to channel args. + // We remove the arg for the parent uuid, since we no longer need it. + grpc_arg new_arg = grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_CHANNELZ_CHANNEL_NODE), channelz_node.get(), + &channelz_node_arg_vtable); + const char* args_to_remove[] = {GRPC_ARG_CHANNELZ_PARENT_UUID}; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( + args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); + grpc_channel_stack_builder_set_channel_arguments(builder, new_args); + grpc_channel_args_destroy(new_args); +} + +} // namespace + grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* input_args, grpc_channel_stack_type channel_stack_type, @@ -219,9 +252,12 @@ grpc_channel* grpc_channel_create(const char* target, } return nullptr; } - grpc_channel* channel = - grpc_channel_create_with_builder(builder, channel_stack_type); - return channel; + // We only need to do this for clients here. For servers, this will be + // done in src/core/lib/surface/server.cc. + if (grpc_channel_stack_type_is_client(channel_stack_type)) { + CreateChannelzNode(builder); + } + return grpc_channel_create_with_builder(builder, channel_stack_type); } size_t grpc_channel_get_call_size_estimate(grpc_channel* channel) { @@ -401,12 +437,21 @@ grpc_call* grpc_channel_create_registered_call( static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); - if (channel->channelz_channel != nullptr) { - channel->channelz_channel->AddTraceEvent( + if (channel->channelz_node != nullptr) { + if (channel->channelz_node->parent_uuid() > 0) { + grpc_core::RefCountedPtr parent_node = + grpc_core::channelz::ChannelzRegistry::Get( + channel->channelz_node->parent_uuid()); + if (parent_node != nullptr) { + grpc_core::channelz::ChannelNode* parent = + static_cast(parent_node.get()); + parent->RemoveChildChannel(channel->channelz_node->uuid()); + } + } + channel->channelz_node->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel destroyed")); - channel->channelz_channel->MarkChannelDestroyed(); - channel->channelz_channel.reset(); + channel->channelz_node.reset(); } grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel)); while (channel->registered_calls) { diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 5d666220745..a4cac748f2d 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -88,7 +88,7 @@ struct grpc_channel { gpr_mu registered_call_mu; registered_call* registered_calls; - grpc_core::RefCountedPtr channelz_channel; + grpc_core::RefCountedPtr channelz_node; char* target; }; @@ -106,7 +106,7 @@ inline grpc_channel_stack* grpc_channel_get_channel_stack( inline grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node( grpc_channel* channel) { - return channel->channelz_channel.get(); + return channel->channelz_node.get(); } #ifndef NDEBUG diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index b3c0b368982..5ac7f0871a4 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -23,6 +23,7 @@ #include #include +#include #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" @@ -174,7 +175,7 @@ TEST(ChannelTracerTest, ComplexTest) { AddSimpleTrace(&tracer); ChannelFixture channel1(kEventListMemoryLimit); RefCountedPtr sc1 = MakeRefCounted( - channel1.channel(), kEventListMemoryLimit, true); + UniquePtr(gpr_strdup("fake_target")), kEventListMemoryLimit, 0); ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, @@ -193,7 +194,7 @@ TEST(ChannelTracerTest, ComplexTest) { ValidateChannelTrace(&tracer, 5); ChannelFixture channel2(kEventListMemoryLimit); RefCountedPtr sc2 = MakeRefCounted( - channel2.channel(), kEventListMemoryLimit, true); + UniquePtr(gpr_strdup("fake_target")), kEventListMemoryLimit, 0); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("LB channel two created"), sc2); @@ -222,7 +223,7 @@ TEST(ChannelTracerTest, TestNesting) { ValidateChannelTrace(&tracer, 2); ChannelFixture channel1(kEventListMemoryLimit); RefCountedPtr sc1 = MakeRefCounted( - channel1.channel(), kEventListMemoryLimit, true); + UniquePtr(gpr_strdup("fake_target")), kEventListMemoryLimit, 0); ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, @@ -231,7 +232,7 @@ TEST(ChannelTracerTest, TestNesting) { AddSimpleTrace(sc1_peer.trace()); ChannelFixture channel2(kEventListMemoryLimit); RefCountedPtr conn1 = MakeRefCounted( - channel2.channel(), kEventListMemoryLimit, true); + UniquePtr(gpr_strdup("fake_target")), kEventListMemoryLimit, 0); ChannelNodePeer conn1_peer(conn1.get()); // nesting one level deeper. sc1_peer.trace()->AddTraceEventWithReference( @@ -245,7 +246,7 @@ TEST(ChannelTracerTest, TestNesting) { ValidateChannelTrace(conn1_peer.trace(), 1); ChannelFixture channel3(kEventListMemoryLimit); RefCountedPtr sc2 = MakeRefCounted( - channel3.channel(), kEventListMemoryLimit, true); + UniquePtr(gpr_strdup("fake_target")), kEventListMemoryLimit, 0); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel two created"), sc2); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index abd1601ad14..7c55f9ffe0f 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -486,8 +486,7 @@ TEST_F(ChannelzRegistryBasedTest, InternalChannelTest) { (void)channels; // suppress unused variable error // create an internal channel grpc_arg client_a[2]; - client_a[0] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL), true); + client_a[0] = grpc_core::channelz::MakeParentUuidArg(1); client_a[1] = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index ced6d9d8027..2c1f988d173 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -72,12 +72,6 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override { - delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - private: void ShutdownLocked() override { delegate_.reset(); } @@ -164,6 +158,10 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy parent_->channel_control_helper()->RequestReresolution(); } + void AddTraceEvent(TraceSeverity severity, const char* message) override { + parent_->channel_control_helper()->AddTraceEvent(severity, message); + } + private: RefCountedPtr parent_; InterceptRecvTrailingMetadataCallback cb_; diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 26ef59fbeb3..69c56c574f9 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -163,13 +163,12 @@ class ChannelzServerTest : public ::testing::Test { } std::unique_ptr NewEchoStub() { - static int salt = 0; string target = "dns:localhost:" + to_string(proxy_port_); ChannelArguments args; // disable channelz. We only want to focus on proxy to backend outbound. args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); // This ensures that gRPC will not do connection sharing. - args.SetInt("salt", salt++); + args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, true); std::shared_ptr channel = ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); return grpc::testing::EchoTestService::NewStub(channel); From f9fcdc015d03c7c4d12eb3ed5202e1a2aa90520a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 7 Jun 2019 09:51:29 -0700 Subject: [PATCH 275/676] Convert ChannelzRegistry to use Map<> instead of InlinedVector<>. --- src/core/lib/channel/channelz_registry.cc | 110 +++++--------------- src/core/lib/channel/channelz_registry.h | 32 ++---- src/core/lib/gprpp/map.h | 10 ++ test/core/channel/channelz_registry_test.cc | 63 ++--------- test/core/gprpp/map_test.cc | 18 ++++ 5 files changed, 68 insertions(+), 165 deletions(-) diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 0c033a14c60..553e1fe97b5 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -18,6 +18,9 @@ #include +#include +#include + #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/channel/channelz_registry.h" @@ -29,8 +32,6 @@ #include #include -#include - namespace grpc_core { namespace channelz { namespace { @@ -51,70 +52,17 @@ ChannelzRegistry* ChannelzRegistry::Default() { return g_channelz_registry; } -ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); } - -ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); } - void ChannelzRegistry::InternalRegister(BaseNode* node) { MutexLock lock(&mu_); - entities_.push_back(node); node->uuid_ = ++uuid_generator_; -} - -void ChannelzRegistry::MaybePerformCompactionLocked() { - constexpr double kEmptinessTheshold = 1. / 3; - double emptiness_ratio = - double(num_empty_slots_) / double(entities_.capacity()); - if (emptiness_ratio > kEmptinessTheshold) { - int front = 0; - for (size_t i = 0; i < entities_.size(); ++i) { - if (entities_[i] != nullptr) { - entities_[front++] = entities_[i]; - } - } - for (int i = 0; i < num_empty_slots_; ++i) { - entities_.pop_back(); - } - num_empty_slots_ = 0; - } -} - -int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid, - bool direct_hit_needed) { - int left = 0; - int right = int(entities_.size() - 1); - while (left <= right) { - int true_middle = left + (right - left) / 2; - int first_non_null = true_middle; - while (first_non_null < right && entities_[first_non_null] == nullptr) { - first_non_null++; - } - if (entities_[first_non_null] == nullptr) { - right = true_middle - 1; - continue; - } - intptr_t uuid = entities_[first_non_null]->uuid(); - if (uuid == target_uuid) { - return int(first_non_null); - } - if (uuid < target_uuid) { - left = first_non_null + 1; - } else { - right = true_middle - 1; - } - } - return direct_hit_needed ? -1 : left; + node_map_[node->uuid_] = node; } void ChannelzRegistry::InternalUnregister(intptr_t uuid) { GPR_ASSERT(uuid >= 1); MutexLock lock(&mu_); GPR_ASSERT(uuid <= uuid_generator_); - int idx = FindByUuidLocked(uuid, true); - GPR_ASSERT(idx >= 0); - entities_[idx] = nullptr; - num_empty_slots_++; - MaybePerformCompactionLocked(); + node_map_.erase(uuid); } RefCountedPtr ChannelzRegistry::InternalGet(intptr_t uuid) { @@ -122,12 +70,13 @@ RefCountedPtr ChannelzRegistry::InternalGet(intptr_t uuid) { if (uuid < 1 || uuid > uuid_generator_) { return nullptr; } - int idx = FindByUuidLocked(uuid, true); - if (idx < 0 || entities_[idx] == nullptr) return nullptr; + auto it = node_map_.find(uuid); + if (it == node_map_.end()) return nullptr; // Found node. Return only if its refcount is not zero (i.e., when we // know that there is no other thread about to destroy it). - if (!entities_[idx]->RefIfNonZero()) return nullptr; - return RefCountedPtr(entities_[idx]); + BaseNode* node = it->second; + if (!node->RefIfNonZero()) return nullptr; + return RefCountedPtr(node); } char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { @@ -138,13 +87,11 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { RefCountedPtr node_after_pagination_limit; { MutexLock lock(&mu_); - const int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); - for (size_t i = start_idx; i < entities_.size(); ++i) { - if (entities_[i] != nullptr && - entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && - entities_[i]->uuid() >= start_channel_id && - entities_[i]->RefIfNonZero()) { + for (auto it = node_map_.lower_bound(start_channel_id); + it != node_map_.end(); ++it) { + BaseNode* node = it->second; + if (node->type() == BaseNode::EntityType::kTopLevelChannel && + node->RefIfNonZero()) { // Check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. @@ -152,10 +99,10 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { // refcount, we need to decrease it, but we can't unref while // holding the lock, because this may lead to a deadlock. if (top_level_channels.size() == kPaginationLimit) { - node_after_pagination_limit.reset(entities_[i]); + node_after_pagination_limit.reset(node); break; } - top_level_channels.emplace_back(entities_[i]); + top_level_channels.emplace_back(node); } } } @@ -186,13 +133,11 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { RefCountedPtr node_after_pagination_limit; { MutexLock lock(&mu_); - const int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); - for (size_t i = start_idx; i < entities_.size(); ++i) { - if (entities_[i] != nullptr && - entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kServer && - entities_[i]->uuid() >= start_server_id && - entities_[i]->RefIfNonZero()) { + for (auto it = node_map_.lower_bound(start_server_id); + it != node_map_.end(); ++it) { + BaseNode* node = it->second; + if (node->type() == BaseNode::EntityType::kServer && + node->RefIfNonZero()) { // Check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. @@ -200,10 +145,10 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { // refcount, we need to decrease it, but we can't unref while // holding the lock, because this may lead to a deadlock. if (servers.size() == kPaginationLimit) { - node_after_pagination_limit.reset(entities_[i]); + node_after_pagination_limit.reset(node); break; } - servers.emplace_back(entities_[i]); + servers.emplace_back(node); } } } @@ -230,9 +175,10 @@ void ChannelzRegistry::InternalLogAllEntities() { InlinedVector, 10> nodes; { MutexLock lock(&mu_); - for (size_t i = 0; i < entities_.size(); ++i) { - if (entities_[i] != nullptr && entities_[i]->RefIfNonZero()) { - nodes.emplace_back(entities_[i]); + for (auto& p : node_map_) { + BaseNode* node = p.second; + if (node->RefIfNonZero()) { + nodes.emplace_back(node); } } } diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index b9d42ecf4d6..e04d7c44888 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -21,19 +21,16 @@ #include +#include + #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/gprpp/inlined_vector.h" - -#include +#include "src/core/lib/gprpp/map.h" +#include "src/core/lib/gprpp/sync.h" namespace grpc_core { namespace channelz { -namespace testing { -class ChannelzRegistryPeer; -} - // singleton registry object to track all objects that are needed to support // channelz bookkeeping. All objects share globally distributed uuids. class ChannelzRegistry { @@ -69,13 +66,6 @@ class ChannelzRegistry { static void LogAllEntities() { Default()->InternalLogAllEntities(); } private: - GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - friend class testing::ChannelzRegistryPeer; - - ChannelzRegistry(); - ~ChannelzRegistry(); - // Returned the singleton instance of ChannelzRegistry; static ChannelzRegistry* Default(); @@ -93,22 +83,12 @@ class ChannelzRegistry { char* InternalGetTopChannels(intptr_t start_channel_id); char* InternalGetServers(intptr_t start_server_id); - // If entities_ has over a certain threshold of empty slots, it will - // compact the vector and move all used slots to the front. - void MaybePerformCompactionLocked(); - - // Performs binary search on entities_ to find the index with that uuid. - // If direct_hit_needed, then will return -1 in case of absence. - // Else, will return idx of the first uuid higher than the target. - int FindByUuidLocked(intptr_t uuid, bool direct_hit_needed); - void InternalLogAllEntities(); // protects members - gpr_mu mu_; - InlinedVector entities_; + Mutex mu_; + Map node_map_; intptr_t uuid_generator_ = 0; - int num_empty_slots_ = 0; }; } // namespace channelz diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h index 525c25347f4..36e32d60c07 100644 --- a/src/core/lib/gprpp/map.h +++ b/src/core/lib/gprpp/map.h @@ -22,8 +22,11 @@ #include #include + +#include #include #include + #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/pair.h" @@ -88,6 +91,13 @@ class Map { iterator end() { return iterator(this, nullptr); } + iterator lower_bound(const Key& k) { + key_compare compare; + return std::find_if(begin(), end(), [&k, &compare](const value_type& v) { + return !compare(v.first, k); + }); + } + private: friend class testing::MapTest; struct Entry { diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index 030d52fd548..deb85d85624 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -43,16 +43,6 @@ namespace grpc_core { namespace channelz { namespace testing { -class ChannelzRegistryPeer { - public: - const InlinedVector* entities() { - return &ChannelzRegistry::Default()->entities_; - } - int num_empty_slots() { - return ChannelzRegistry::Default()->num_empty_slots_; - } -}; - class ChannelzRegistryTest : public ::testing::Test { protected: // ensure we always have a fresh registry for tests. @@ -115,38 +105,15 @@ TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) { EXPECT_EQ(channelz_channel, retrieved); } -TEST_F(ChannelzRegistryTest, TestCompaction) { - const int kLoopIterations = 300; - // These channels that will stay in the registry for the duration of the test. - std::vector> even_channels; - even_channels.reserve(kLoopIterations); - { - // The channels will unregister themselves at the end of the for block. - std::vector> odd_channels; - odd_channels.reserve(kLoopIterations); - for (int i = 0; i < kLoopIterations; i++) { - even_channels.push_back( - MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); - odd_channels.push_back( - MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); - } - } - // without compaction, there would be exactly kLoopIterations empty slots at - // this point. However, one of the unregisters should have triggered - // compaction. - ChannelzRegistryPeer peer; - EXPECT_LT(peer.num_empty_slots(), kLoopIterations); -} - -TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) { +TEST_F(ChannelzRegistryTest, TestUnregistration) { const int kLoopIterations = 100; - // These channels that will stay in the registry for the duration of the test. + // These channels will stay in the registry for the duration of the test. std::vector> even_channels; even_channels.reserve(kLoopIterations); std::vector odd_uuids; odd_uuids.reserve(kLoopIterations); { - // The channels will unregister themselves at the end of the for block. + // These channels will unregister themselves at the end of this block. std::vector> odd_channels; odd_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { @@ -157,6 +124,7 @@ TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) { odd_uuids.push_back(odd_channels[i]->uuid()); } } + // Check that the even channels are present and the odd channels are not. for (int i = 0; i < kLoopIterations; i++) { RefCountedPtr retrieved = ChannelzRegistry::Get(even_channels[i]->uuid()); @@ -164,27 +132,8 @@ TEST_F(ChannelzRegistryTest, TestGetAfterCompaction) { retrieved = ChannelzRegistry::Get(odd_uuids[i]); EXPECT_EQ(retrieved, nullptr); } -} - -TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) { - const int kLoopIterations = 100; - // These channels that will stay in the registry for the duration of the test. - std::vector> even_channels; - even_channels.reserve(kLoopIterations); - std::vector odd_uuids; - odd_uuids.reserve(kLoopIterations); - { - // The channels will unregister themselves at the end of the for block. - std::vector> odd_channels; - odd_channels.reserve(kLoopIterations); - for (int i = 0; i < kLoopIterations; i++) { - even_channels.push_back( - MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); - odd_channels.push_back( - MakeRefCounted(BaseNode::EntityType::kTopLevelChannel)); - odd_uuids.push_back(odd_channels[i]->uuid()); - } - } + // Add more channels and verify that they get added correctly, to make + // sure that the unregistration didn't leave the registry in a weird state. std::vector> more_channels; more_channels.reserve(kLoopIterations); for (int i = 0; i < kLoopIterations; i++) { diff --git a/test/core/gprpp/map_test.cc b/test/core/gprpp/map_test.cc index 6e70a2a2ac2..30d9eb0b207 100644 --- a/test/core/gprpp/map_test.cc +++ b/test/core/gprpp/map_test.cc @@ -419,6 +419,24 @@ TEST_F(MapTest, RandomOpsWithIntKey) { EXPECT_TRUE(test_map.empty()); } +// Tests lower_bound(). +TEST_F(MapTest, LowerBound) { + Map test_map; + for (int i = 0; i < 10; i += 2) { + test_map.emplace(i, Payload(i)); + } + auto it = test_map.lower_bound(-1); + EXPECT_EQ(it, test_map.begin()); + it = test_map.lower_bound(0); + EXPECT_EQ(it, test_map.begin()); + it = test_map.lower_bound(2); + EXPECT_EQ(it->first, 2); + it = test_map.lower_bound(3); + EXPECT_EQ(it->first, 4); + it = test_map.lower_bound(9); + EXPECT_EQ(it, test_map.end()); +} + } // namespace testing } // namespace grpc_core From 79ffaced7d01a38d7ba0aa37ce75767420cbaa8e Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 7 Jun 2019 10:09:07 -0700 Subject: [PATCH 276/676] Add python 3.8 test --- .../Dockerfile.template | 28 +++++++ .../test/python_stretch_3.8_x64/Dockerfile | 79 +++++++++++++++++++ .../python_stretch_3.8_x64/get_cpython.sh | 15 ++++ tools/run_tests/run_tests.py | 13 ++- 4 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 templates/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile.template create mode 100644 tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile create mode 100644 tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh diff --git a/templates/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile.template new file mode 100644 index 00000000000..8f2585a4d59 --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile.template @@ -0,0 +1,28 @@ + +%YAML 1.2 +--- | + # Copyright 2019 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> + RUN apt-get install -y jq zlib1g-dev libssl-dev + + COPY get_cpython.sh /tmp + RUN apt-get install -y jq build-essential libffi-dev && ${'\\'} + chmod +x /tmp/get_cpython.sh && ${'\\'} + /tmp/get_cpython.sh && ${'\\'} + rm /tmp/get_cpython.sh + + RUN python3.8 -m ensurepip && ${'\\'} + python3.8 -m pip install coverage diff --git a/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile new file mode 100644 index 00000000000..d5ecbc7110a --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.8_x64/Dockerfile @@ -0,0 +1,79 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + +RUN apt-get install -y jq zlib1g-dev libssl-dev + +COPY get_cpython.sh /tmp +RUN apt-get install -y jq build-essential libffi-dev && \ + chmod +x /tmp/get_cpython.sh && \ + /tmp/get_cpython.sh && \ + rm /tmp/get_cpython.sh + +RUN python3.8 -m ensurepip && \ + python3.8 -m pip install coverage diff --git a/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh b/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh new file mode 100644 index 00000000000..c01c6ebb0d2 --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +VERSION_REGEX="v3.8.*" +REPO="python/cpython" + +LATEST=$(curl -s https://api.github.com/repos/$REPO/tags | \ + jq -r '.[] | select(.name|test("'$VERSION_REGEX'")) | .name' \ + | sort | tail -n1) + +wget https://github.com/$REPO/archive/$LATEST.tar.gz +tar xzvf *.tar.gz +( cd cpython* + ./configure + make install +) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index a7a9dbd48d0..108cf29c0a8 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -753,7 +753,7 @@ class PythonLanguage(object): def _python_manager_name(self): """Choose the docker image to use based on python version.""" if self.args.compiler in [ - 'python2.7', 'python3.5', 'python3.6', 'python3.7' + 'python2.7', 'python3.5', 'python3.6', 'python3.7', 'python3.8' ]: return 'stretch_' + self.args.compiler[len('python'):] elif self.args.compiler == 'python_alpine': @@ -829,6 +829,12 @@ class PythonLanguage(object): minor='7', bits=bits, config_vars=config_vars) + python38_config = _python_config_generator( + name='py38', + major='3', + minor='8', + bits=bits, + config_vars=config_vars) pypy27_config = _pypy_config_generator( name='pypy', major='2', config_vars=config_vars) pypy32_config = _pypy_config_generator( @@ -852,6 +858,8 @@ class PythonLanguage(object): return (python36_config,) elif args.compiler == 'python3.7': return (python37_config,) + elif args.compiler == 'python3.8': + return (python38_config,) elif args.compiler == 'pypy': return (pypy27_config,) elif args.compiler == 'pypy3': @@ -865,6 +873,7 @@ class PythonLanguage(object): python35_config, python36_config, python37_config, + # TODO: Add Python 3.8 once it's released. ) else: raise Exception('Compiler %s not supported.' % args.compiler) @@ -1340,7 +1349,7 @@ argp.add_argument( choices=[ 'default', 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc7.2', 'gcc_musl', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'clang7.0', - 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', 'pypy', + 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', 'python3.8', 'pypy', 'pypy3', 'python_alpine', 'all_the_cpythons', 'electron1.3', 'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015', 'cmake_vs2017' ], From 2b6e7c44235522c125dbc14e6b82e18c8aab62cd Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 8 May 2019 14:29:11 -0700 Subject: [PATCH 277/676] Added some Objective C tests and minor bug fixes. Objective-C tests: metadata, compression, keepalives, channel args. Stress tests: network flap while streaming call in progress. Bug fixes: Stream gzip handling in interop server. Keep alive, backoff time truncation bug in Obj-C layer. --- .../GRPCClient/GRPCCall+ChannelArg.m | 3 + src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 10 +- .../GRPCClient/private/GRPCChannel.m | 2 + .../GRPCClient/private/GRPCChannelPool.m | 4 +- src/objective-c/GRPCClient/private/GRPCHost.m | 10 +- .../InteropTestsRemoteWithCronet.m | 4 + .../tests/InteropTests/InteropTests.h | 6 + .../tests/InteropTests/InteropTests.m | 190 ++++++++- .../tests/InteropTests/InteropTestsRemote.m | 4 + src/objective-c/tests/MacTests/StressTests.m | 383 +++++++++++++++++- src/objective-c/tests/UnitTests/APIv2Tests.m | 330 ++++++++++++++- test/cpp/interop/interop_server.cc | 3 +- 13 files changed, 921 insertions(+), 33 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index ae60d6208e1..78fe687b3d4 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -51,6 +51,9 @@ case GRPCCompressGzip: hostConfig.compressAlgorithm = GRPC_COMPRESS_GZIP; break; + case GRPCStreamCompressGzip: + hostConfig.compressAlgorithm = GRPC_COMPRESS_STREAM_GZIP; + break; default: NSLog(@"Invalid compression algorithm"); abort(); diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index 98511e3f5cb..b957e11fbea 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -156,7 +156,8 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the // call should wait for PING ACK. If PING ACK is not received after this period, the call fails. -// Negative values are not allowed. +// Negative values are invalid; setting these parameters to negative value will reset the +// corresponding parameter to the internal default value. @property(readonly) NSTimeInterval keepaliveInterval; @property(readonly) NSTimeInterval keepaliveTimeout; @@ -320,7 +321,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the // call should wait for PING ACK. If PING ACK is not received after this period, the call fails. // Negative values are invalid; setting these parameters to negative value will reset the -// corresponding parameter to 0. +// corresponding parameter to the internal default value. @property(readwrite) NSTimeInterval keepaliveInterval; @property(readwrite) NSTimeInterval keepaliveTimeout; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index 392e42a9d47..f02486a7c44 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -30,7 +30,7 @@ static const NSUInteger kDefaultResponseSizeLimit = 0; static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; static const BOOL kDefaultRetryEnabled = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; -static const NSTimeInterval kDefaultKeepaliveTimeout = 0; +static const NSTimeInterval kDefaultKeepaliveTimeout = -1; static const NSTimeInterval kDefaultConnectMinTimeout = 0; static const NSTimeInterval kDefaultConnectInitialBackoff = 0; static const NSTimeInterval kDefaultConnectMaxBackoff = 0; @@ -181,7 +181,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _compressionAlgorithm = compressionAlgorithm; _retryEnabled = retryEnabled; _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; - _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout; + _keepaliveTimeout = keepaliveTimeout; _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; @@ -486,11 +486,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { } - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { - if (keepaliveTimeout < 0) { - _keepaliveTimeout = 0; - } else { - _keepaliveTimeout = keepaliveTimeout; - } + _keepaliveTimeout = keepaliveTimeout; } - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 1a79fb04a0d..4a187ae9081 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,6 +109,8 @@ if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; + } + if (_callOptions.keepaliveTimeout >= 0) { args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 60a33eda824..24ed83d3341 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -118,9 +118,7 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _lastTimedDestroy = nil; grpc_call *unmanagedCall = - [_wrappedChannel unmanagedCallWithPath:path - completionQueue:[GRPCCompletionQueue completionQueue] - callOptions:callOptions]; + [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; if (unmanagedCall == NULL) { NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); return nil; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 24348c3aed7..c4287731efd 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -105,11 +105,11 @@ static NSMutableDictionary *gHostCache; options.responseSizeLimit = _responseSizeLimitOverride; options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; options.retryEnabled = _retryEnabled; - options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; - options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; - options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; - options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; - options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; + options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000.0; + options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000.0; + options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000.0; + options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000.0; + options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000.0; options.PEMRootCertificates = _PEMRootCertificates; options.PEMPrivateKey = _PEMPrivateKey; options.PEMCertificateChain = _PEMCertificateChain; diff --git a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m index a2a79c46316..30741e9a0da 100644 --- a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m +++ b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m @@ -48,6 +48,10 @@ static int32_t kRemoteInteropServerOverhead = 12; return YES; } ++ (BOOL)canRunCompressionTest { + return NO; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } diff --git a/src/objective-c/tests/InteropTests/InteropTests.h b/src/objective-c/tests/InteropTests/InteropTests.h index cffa90ac497..0c896ae18a8 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.h +++ b/src/objective-c/tests/InteropTests/InteropTests.h @@ -64,4 +64,10 @@ */ + (BOOL)useCronet; +/** + * Whether we can run compression tests in the test suite. + */ + ++ (BOOL)canRunCompressionTest; + @end diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 7d4aee0bc90..aa7a41163d4 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -347,6 +347,10 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager return NO; } ++ (BOOL)canRunCompressionTest { + return YES; +} + + (void)setUp { #ifdef GRPC_COMPILE_WITH_CRONET configureCronet(); @@ -430,10 +434,16 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block BOOL messageReceived = NO; __block BOOL done = NO; + __block BOOL initialMetadataReceived = YES; NSCondition *cond = [[NSCondition alloc] init]; GRPCUnaryProtoCall *call = [_service emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [cond lock]; + initialMetadataReceived = YES; + [cond unlock]; + } messageCallback:^(id message) { if (message) { id expectedResponse = [GPBEmpty message]; @@ -459,6 +469,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager while (!done && [deadline timeIntervalSinceNow] > 0) { [cond waitUntilDate:deadline]; } + XCTAssertTrue(initialMetadataReceived); XCTAssertTrue(messageReceived); XCTAssertTrue(done); [cond unlock]; @@ -1014,6 +1025,78 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)testInitialMetadataWithV2API { + __weak XCTestExpectation *initialMetadataReceived = + [self expectationWithDescription:@"Received initial metadata."]; + __weak XCTestExpectation *closeReceived = [self expectationWithDescription:@"RPC completed."]; + + __block NSDictionary *init_md = + [NSDictionary dictionaryWithObjectsAndKeys:@"FOOBAR", @"x-grpc-test-echo-initial", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.initialMetadata = init_md; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + RMTSimpleRequest *request = [RMTSimpleRequest message]; + __block bool init_md_received = NO; + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + XCTAssertEqualObjects(initialMetadata[@"x-grpc-test-echo-initial"], + init_md[@"x-grpc-test-echo-initial"]); + init_md_received = YES; + [initialMetadataReceived fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [closeReceived fulfill]; + }] + callOptions:options]; + + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testTrailingMetadataWithV2API { + // This test needs to be disabled for remote test because interop server grpc-test + // does not send trailing binary metadata. + if (isRemoteInteropTest([[self class] host])) { + return; + } + + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"Received trailing metadata."]; + const unsigned char raw_bytes[] = {0x1, 0x2, 0x3, 0x4}; + NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)]; + __block NSDictionary *trailer = [NSDictionary + dictionaryWithObjectsAndKeys:trailer_data, @"x-grpc-test-echo-trailing-bin", nil]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.initialMetadata = trailer; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + RMTSimpleRequest *request = [RMTSimpleRequest message]; + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler: + [[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + XCTAssertEqualObjects( + trailingMetadata[@"x-grpc-test-echo-trailing-bin"], + trailer[@"x-grpc-test-echo-trailing-bin"]); + [expectation fulfill]; + }] + callOptions:options]; + [call start]; + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + - (void)testCancelAfterFirstResponseRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = @@ -1148,13 +1231,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testCompressedUnaryRPC { - // This test needs to be disabled for remote test because interop server grpc-test - // does not support compression. - if (isRemoteInteropTest([[self class] host])) { - return; - } - XCTAssertNotNil([[self class] host]); +- (void)RPCWithCompressMethod:(GRPCCompressionAlgorithm)compressMethod { __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -1162,7 +1239,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; request.expectCompressed.value = YES; - [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]]; + [GRPCCall setDefaultCompressMethod:compressMethod forhost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -1179,6 +1256,67 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } +- (void)RPCWithCompressMethodWithV2API:(GRPCCompressionAlgorithm)compressMethod { + __weak XCTestExpectation *expectMessage = + [self expectationWithDescription:@"Reived response from server."]; + __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"RPC completed."]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = 314159; + request.payload.body = [NSMutableData dataWithLength:271828]; + request.expectCompressed.value = YES; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + options.compressionAlgorithm = compressMethod; + + GRPCUnaryProtoCall *call = [_service + unaryCallWithMessage:request + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertNotNil(message); + if (message) { + RMTSimpleResponse *expectedResponse = + [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = + [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(message, expectedResponse); + + [expectMessage fulfill]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [expectComplete fulfill]; + }] + callOptions:options]; + [call start]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testCompressedUnaryRPC { + if ([[self class] canRunCompressionTest]) { + for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate; + compress <= GRPCStreamCompressGzip; ++compress) { + [self RPCWithCompressMethod:compress]; + } + } +} + +- (void)testCompressedUnaryRPCWithV2API { + if ([[self class] canRunCompressionTest]) { + for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate; + compress <= GRPCStreamCompressGzip; ++compress) { + [self RPCWithCompressMethodWithV2API:compress]; + } + } +} + #ifndef GRPC_COMPILE_WITH_CRONET - (void)testKeepalive { XCTAssertNotNil([[self class] host]); @@ -1220,6 +1358,40 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } + +- (void)testKeepaliveWithV2API { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"]; + + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = self.class.transportType; + options.PEMRootCertificates = self.class.PEMRootCertificates; + options.hostNameOverride = [[self class] hostNameOverride]; + options.keepaliveInterval = 1.5; + options.keepaliveTimeout = 0; + + id request = + [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; + + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^( + NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNotNil(error); + XCTAssertEqual( + error.code, + GRPC_STATUS_UNAVAILABLE); + [expectation fulfill]; + }] + callOptions:options]; + [call start]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} #endif - (void)testDefaultInterceptor { diff --git a/src/objective-c/tests/InteropTests/InteropTestsRemote.m b/src/objective-c/tests/InteropTests/InteropTestsRemote.m index c1cd9b81efc..7bd5b28780c 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTests/InteropTestsRemote.m @@ -49,6 +49,10 @@ static int32_t kRemoteInteropServerOverhead = 12; return nil; } ++ (BOOL)canRunCompressionTest { + return NO; +} + - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } diff --git a/src/objective-c/tests/MacTests/StressTests.m b/src/objective-c/tests/MacTests/StressTests.m index 22174b58665..7475dc77fcc 100644 --- a/src/objective-c/tests/MacTests/StressTests.m +++ b/src/objective-c/tests/MacTests/StressTests.m @@ -29,7 +29,7 @@ #import #import -#define TEST_TIMEOUT 32 +#define TEST_TIMEOUT 64 extern const char *kCFStreamVarName; @@ -136,7 +136,11 @@ extern const char *kCFStreamVarName; return GRPCTransportTypeChttp2BoringSSL; } -- (void)testNetworkFlapWithV2API { +- (int)getRandomNumberBetween:(int)min max:(int)max { + return min + arc4random_uniform((max - min + 1)); +} + +- (void)testNetworkFlapOnUnaryCallWithV2API { NSMutableArray *completeExpectations = [NSMutableArray array]; NSMutableArray *calls = [NSMutableArray array]; int num_rpcs = 100; @@ -175,6 +179,7 @@ extern const char *kCFStreamVarName; UTF8String]); address_removed = YES; } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); system([ [NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] @@ -196,7 +201,241 @@ extern const char *kCFStreamVarName; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testNetworkFlapWithV1API { +- (void)testNetworkFlapOnClientStreamingCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + GRPCStreamingProtoCall *call = [_service + streamingInputCallWithResponseHandler: + [[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message]; + request1.payload.body = [NSMutableData dataWithLength:27182]; + RMTStreamingInputCallRequest *request2 = [RMTStreamingInputCallRequest message]; + request2.payload.body = [NSMutableData dataWithLength:8]; + + [call writeMessage:request1]; + [NSThread sleepForTimeInterval:0.1f]; + [call writeMessage:request2]; + [call finish]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapOnServerStreamingCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + for (int i = 0; i < 5; i++) { + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 10000; + [request.responseParametersArray addObject:parameters]; + } + + request.payload.body = [NSMutableData dataWithLength:100]; + + GRPCUnaryProtoCall *call = [_service + streamingOutputCallWithMessage:request + responseHandler: + [[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat: + @"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); + system([[NSString + stringWithFormat: + @"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + [NSThread sleepForTimeInterval:0.1f]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapOnHalfDuplexCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + GRPCStreamingProtoCall *call = [_service + halfDuplexCallWithResponseHandler: + [[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + RMTStreamingOutputCallRequest *request1 = [RMTStreamingOutputCallRequest message]; + RMTStreamingOutputCallRequest *request2 = [RMTStreamingOutputCallRequest message]; + for (int i = 0; i < 5; i++) { + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 1000; + [request1.responseParametersArray addObject:parameters]; + [request2.responseParametersArray addObject:parameters]; + } + + request1.payload.body = [NSMutableData dataWithLength:100]; + request2.payload.body = [NSMutableData dataWithLength:100]; + + [call writeMessage:request1]; + [NSThread sleepForTimeInterval:0.1f]; + [call writeMessage:request2]; + [call finish]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapOnFullDuplexCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + __block BOOL address_removed = FALSE; + __block BOOL address_readded = FALSE; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler: + [[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + @synchronized(self) { + if (error == nil && !address_removed) { + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 -alias %@", + [[self class] hostAddress]] + UTF8String]); + address_removed = YES; + } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); + system([[NSString + stringWithFormat:@"sudo ifconfig lo0 alias %@", + [[self class] hostAddress]] + UTF8String]); + address_readded = YES; + } + } + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 1000; + for (int i = 0; i < 5; i++) { + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:100]; + [call writeMessage:request]; + } + [call finish]; + [NSThread sleepForTimeInterval:0.1f]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testNetworkFlapOnUnaryCallWithV1API { NSMutableArray *completeExpectations = [NSMutableArray array]; int num_rpcs = 100; __block BOOL address_removed = FALSE; @@ -220,6 +459,7 @@ extern const char *kCFStreamVarName; UTF8String]); address_removed = YES; } else if (error != nil && !address_readded) { + XCTAssertTrue(address_removed); system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] UTF8String]); @@ -234,4 +474,141 @@ extern const char *kCFStreamVarName; } } +- (void)testTimeoutOnFullDuplexCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.timeout = 0.3; + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler: + [[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + if (error != nil) { + XCTAssertEqual(error.code, GRPC_STATUS_DEADLINE_EXCEEDED); + } + [completeExpectations[i] fulfill]; + }] + callOptions:options]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 1000; + // delay response by 100-200 milliseconds + parameters.intervalUs = [self getRandomNumberBetween:100 * 1000 max:200 * 1000]; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:100]; + + [call writeMessage:request]; + [call writeMessage:request]; + [call finish]; + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testServerStreamingCallSlowClientWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + for (int i = 0; i < 5; i++) { + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 10000; + [request.responseParametersArray addObject:parameters]; + [request.responseParametersArray addObject:parameters]; + [request.responseParametersArray addObject:parameters]; + [request.responseParametersArray addObject:parameters]; + [request.responseParametersArray addObject:parameters]; + } + + request.payload.body = [NSMutableData dataWithLength:100]; + + GRPCUnaryProtoCall *call = [_service + streamingOutputCallWithMessage:request + responseHandler:[[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + // inject a delay + [NSThread sleepForTimeInterval:0.5f]; + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, @"Unexpected error: %@", error); + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + dispatch_async(q, ^{ + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + }); + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + +- (void)testCancelOnFullDuplexCallWithV2API { + NSMutableArray *completeExpectations = [NSMutableArray array]; + NSMutableArray *calls = [NSMutableArray array]; + int num_rpcs = 100; + dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); + for (int i = 0; i < num_rpcs; ++i) { + [completeExpectations + addObject:[self expectationWithDescription: + [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; + + GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[MacTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:nil + closeCallback:^( + NSDictionary *trailingMetadata, + NSError *error) { + [completeExpectations[i] fulfill]; + }] + callOptions:nil]; + [calls addObject:call]; + } + + for (int i = 0; i < num_rpcs; ++i) { + GRPCStreamingProtoCall *call = calls[i]; + [call start]; + dispatch_async(q, ^{ + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = 1000; + for (int i = 0; i < 100; i++) { + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + [request.responseParametersArray addObject:parameters]; + [call writeMessage:request]; + } + [NSThread sleepForTimeInterval:0.01f]; + [call cancel]; + }); + } + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +} + @end diff --git a/src/objective-c/tests/UnitTests/APIv2Tests.m b/src/objective-c/tests/UnitTests/APIv2Tests.m index db293750ca3..066800613f6 100644 --- a/src/objective-c/tests/UnitTests/APIv2Tests.m +++ b/src/objective-c/tests/UnitTests/APIv2Tests.m @@ -21,6 +21,11 @@ #import #import +#import "../../GRPCClient/private/GRPCCallInternal.h" +#import "../../GRPCClient/private/GRPCChannel.h" +#import "../../GRPCClient/private/GRPCChannelPool.h" +#import "../../GRPCClient/private/GRPCWrappedCall.h" + #include #include @@ -48,12 +53,41 @@ static const int kSimpleDataLength = 100; static const NSTimeInterval kTestTimeout = 8; static const NSTimeInterval kInvertedTimeout = 2; -// Reveal the _class ivar for testing access +// Reveal the _class ivars for testing access @interface GRPCCall2 () { + @public + id _firstInterceptor; +} +@end + +@interface GRPCCall2Internal () { @public GRPCCall *_call; } +@end + +@interface GRPCCall () { + @public + GRPCWrappedCall *_wrappedCall; +} +@end + +@interface GRPCWrappedCall () { + @public + GRPCPooledChannel *_pooledChannel; +} +@end + +@interface GRPCPooledChannel () { + @public + GRPCChannel *_wrappedChannel; +} +@end +@interface GRPCChannel () { + @public + grpc_channel *_unmanagedChannel; +} @end // Convenience class to use blocks as callbacks @@ -148,6 +182,7 @@ static const NSTimeInterval kInvertedTimeout = 2; kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"StreamingOutputCall"]; + kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; } @@ -179,7 +214,7 @@ static const NSTimeInterval kInvertedTimeout = 2; closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { trailing_md = trailingMetadata; if (error) { - XCTAssertEqual(error.code, 16, + XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated, @"Finished with unexpected error: %@", error); XCTAssertEqualObjects(init_md, error.userInfo[kGRPCHeadersKey]); @@ -759,7 +794,7 @@ static const NSTimeInterval kInvertedTimeout = 2; } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNotNil(error, @"Expecting non-nil error"); - XCTAssertEqual(error.code, 2); + XCTAssertEqual(error.code, GRPCErrorCodeUnknown); [completion fulfill]; }] callOptions:options]; @@ -770,4 +805,293 @@ static const NSTimeInterval kInvertedTimeout = 2; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } +- (void)testAdditionalChannelArgs { + __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kUnaryCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + // set max message length = 1 byte. + options.additionalChannelArgs = + [NSDictionary dictionaryWithObjectsAndKeys:@1, @GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, nil]; + options.transportType = GRPCTransportTypeInsecure; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; + + GRPCCall2 *call = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil + messageCallback:^(NSData *data) { + XCTFail(@"Received unexpected message"); + } + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + XCTAssertNotNil(error, @"Expecting non-nil error"); + NSLog(@"Got error: %@", error); + XCTAssertEqual(error.code, GRPCErrorCodeResourceExhausted, + @"Finished with unexpected error: %@", error); + + [completion fulfill]; + }] + callOptions:options]; + [call writeData:[request data]]; + [call start]; + [call finish]; + + [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; +} + +- (void)testChannelReuseIdentical { + __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; + __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; + NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; + __weak XCTestExpectation *metadata1 = + [self expectationWithDescription:@"Received initial metadata for RPC1."]; + __weak XCTestExpectation *metadata2 = + [self expectationWithDescription:@"Received initial metadata for RPC2."]; + NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; + callOptions.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call1 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata1 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion1 fulfill]; + }] + callOptions:callOptions]; + GRPCCall2 *call2 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata2 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion2 fulfill]; + }] + callOptions:callOptions]; + [call1 start]; + [call2 start]; + [call1 writeData:[request data]]; + [call2 writeData:[request data]]; + [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; + GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; + GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; + XCTAssertEqual( + internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, + internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); + [call1 finish]; + [call2 finish]; + [self waitForExpectations:rpcDone timeout:kTestTimeout]; +} + +- (void)testChannelReuseDifferentCallSafety { + __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; + __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; + NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; + __weak XCTestExpectation *metadata1 = + [self expectationWithDescription:@"Received initial metadata for RPC1."]; + __weak XCTestExpectation *metadata2 = + [self expectationWithDescription:@"Received initial metadata for RPC2."]; + NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *requestOptions1 = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCRequestOptions *requestOptions2 = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyIdempotentRequest]; + + GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; + callOptions.transportType = GRPCTransportTypeInsecure; + GRPCCall2 *call1 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions1 + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata1 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion1 fulfill]; + }] + callOptions:callOptions]; + GRPCCall2 *call2 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions2 + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata2 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion2 fulfill]; + }] + callOptions:callOptions]; + [call1 start]; + [call2 start]; + [call1 writeData:[request data]]; + [call2 writeData:[request data]]; + [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; + GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; + GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; + XCTAssertEqual( + internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, + internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); + [call1 finish]; + [call2 finish]; + [self waitForExpectations:rpcDone timeout:kTestTimeout]; +} + +- (void)testChannelReuseDifferentHost { + __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; + __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; + NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; + __weak XCTestExpectation *metadata1 = + [self expectationWithDescription:@"Received initial metadata for RPC1."]; + __weak XCTestExpectation *metadata2 = + [self expectationWithDescription:@"Received initial metadata for RPC2."]; + NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *requestOptions1 = + [[GRPCRequestOptions alloc] initWithHost:@"[::1]:5050" + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCRequestOptions *requestOptions2 = + [[GRPCRequestOptions alloc] initWithHost:@"127.0.0.1:5050" + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + + GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; + callOptions.transportType = GRPCTransportTypeInsecure; + + GRPCCall2 *call1 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions1 + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata1 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion1 fulfill]; + }] + callOptions:callOptions]; + GRPCCall2 *call2 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions2 + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata2 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion2 fulfill]; + }] + callOptions:callOptions]; + [call1 start]; + [call2 start]; + [call1 writeData:[request data]]; + [call2 writeData:[request data]]; + [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; + GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; + GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; + XCTAssertNotEqual( + internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, + internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); + [call1 finish]; + [call2 finish]; + [self waitForExpectations:rpcDone timeout:kTestTimeout]; +} + +- (void)testChannelReuseDifferentChannelArgs { + __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; + __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; + NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; + __weak XCTestExpectation *metadata1 = + [self expectationWithDescription:@"Received initial metadata for RPC1."]; + __weak XCTestExpectation *metadata2 = + [self expectationWithDescription:@"Received initial metadata for RPC2."]; + NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; + + RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kSimpleDataLength; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; + + GRPCRequestOptions *requestOptions = + [[GRPCRequestOptions alloc] initWithHost:kHostAddress + path:kFullDuplexCallMethod.HTTPPath + safety:GRPCCallSafetyDefault]; + GRPCMutableCallOptions *callOptions1 = [[GRPCMutableCallOptions alloc] init]; + callOptions1.transportType = GRPCTransportTypeInsecure; + GRPCMutableCallOptions *callOptions2 = [[GRPCMutableCallOptions alloc] init]; + callOptions2.transportType = GRPCTransportTypeInsecure; + callOptions2.channelID = 2; + + GRPCCall2 *call1 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata1 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion1 fulfill]; + }] + callOptions:callOptions1]; + GRPCCall2 *call2 = [[GRPCCall2 alloc] + initWithRequestOptions:requestOptions + responseHandler:[[ClientTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { + [metadata2 fulfill]; + } + messageCallback:nil + closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { + [completion2 fulfill]; + }] + callOptions:callOptions2]; + [call1 start]; + [call2 start]; + [call1 writeData:[request data]]; + [call2 writeData:[request data]]; + [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; + GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; + GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; + XCTAssertNotEqual( + internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, + internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); + [call1 finish]; + [call2 finish]; + [self waitForExpectations:rpcDone timeout:kTestTimeout]; +} + @end diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 6570bbf9696..cf55efa5409 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -118,7 +118,8 @@ bool CheckExpectedCompression(const ServerContext& context, "Expected compression but got uncompressed request from client."); return false; } - if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)) { + if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS) && + received_compression != GRPC_COMPRESS_STREAM_GZIP) { gpr_log(GPR_ERROR, "Failure: Requested compression in a compressable request, but " "compression bit in message flags not set."); From eb48acd9272291cdb357289ee98ff316fc5c9992 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 7 Jun 2019 11:33:26 -0700 Subject: [PATCH 278/676] Add copyright header --- .../test/python_stretch_3.8_x64/get_cpython.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh b/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh index c01c6ebb0d2..e051e974b38 100644 --- a/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh +++ b/tools/dockerfile/test/python_stretch_3.8_x64/get_cpython.sh @@ -1,5 +1,19 @@ #!/bin/bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + VERSION_REGEX="v3.8.*" REPO="python/cpython" From 21bf2a2a839ed87883b8d1400141c1b911ee02d5 Mon Sep 17 00:00:00 2001 From: John Luo Date: Fri, 7 Jun 2019 11:56:37 -0700 Subject: [PATCH 279/676] Better fix --- src/csharp/Grpc.Tools/ProtoCompile.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index b6fd94209d2..36a0ea36cee 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -136,7 +136,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'[^\\(]+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + pattern: "^(?'FILENAME'.+?)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -162,7 +162,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'[^\\(]+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + pattern: "^(?'FILENAME'.+?)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -188,7 +188,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'[^:]+): ?warning: ?(?'TEXT'.*)", + pattern: "^(?'FILENAME'.+?): ?warning: ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => @@ -211,7 +211,7 @@ namespace Grpc.Tools new ErrorListFilter { Pattern = new Regex( - pattern: "(?'FILENAME'[^:]+): ?(?'TEXT'.*)", + pattern: "^(?'FILENAME'.+?): ?(?'TEXT'.*)", options: RegexOptions.Compiled | RegexOptions.IgnoreCase, matchTimeout: s_regexTimeout), LogAction = (log, match) => From 385beb95ce5c77126b9a4c85a84c6a86a6222cf3 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 7 Jun 2019 13:12:51 -0700 Subject: [PATCH 280/676] Yapf --- tools/run_tests/run_tests.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 108cf29c0a8..43d8c64da0b 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1349,9 +1349,10 @@ argp.add_argument( choices=[ 'default', 'gcc4.4', 'gcc4.6', 'gcc4.8', 'gcc4.9', 'gcc5.3', 'gcc7.2', 'gcc_musl', 'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7', 'clang7.0', - 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', 'python3.8', 'pypy', - 'pypy3', 'python_alpine', 'all_the_cpythons', 'electron1.3', - 'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015', 'cmake_vs2017' + 'python2.7', 'python3.4', 'python3.5', 'python3.6', 'python3.7', + 'python3.8', 'pypy', 'pypy3', 'python_alpine', 'all_the_cpythons', + 'electron1.3', 'electron1.6', 'coreclr', 'cmake', 'cmake_vs2015', + 'cmake_vs2017' ], default='default', help= From 9601b46ffa10b68ea54453ac5cdf62bcf19f834f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Jun 2019 15:10:49 -0700 Subject: [PATCH 281/676] Resolving testResponsesOver4MBAreAcceptedIfOptedIn delayed callback --- src/objective-c/tests/InteropTests/InteropTests.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 7d4aee0bc90..4bdacbe4fa8 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -18,6 +18,8 @@ #import "InteropTests.h" +#import + #include #ifdef GRPC_COMPILE_WITH_CRONET @@ -701,21 +703,21 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"HigherResponseSizeLimit"]; + __block NSError *callError = nil; RMTSimpleRequest *request = [RMTSimpleRequest message]; const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB request.responseSize = kPayloadSize; [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:[[self class] host]]; - [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { - XCTAssertNil(error, @"Finished with unexpected error: %@", error); - XCTAssertEqual(response.payload.body.length, kPayloadSize); + callError = error; [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + XCTAssertNil(callError, @"Finished with unexpected error: %@", callError); } - (void)testClientStreamingRPC { From 45a0e5bd4f9c673429b6a7f7a3207a2b0cd9564d Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Fri, 7 Jun 2019 11:09:12 -0700 Subject: [PATCH 282/676] Clean up Channel.__del__ logic --- src/python/grpcio/grpc/_channel.py | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index f566fd698ad..4b761bfe5f8 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -966,11 +966,6 @@ def _poll_connectivity(state, channel, initial_try_to_connect): _spawn_delivery(state, callbacks) -def _moot(state): - with state.lock: - del state.callbacks_and_connectivities[:] - - def _subscribe(state, callback, try_to_connect): with state.lock: if not state.callbacks_and_connectivities and not state.polling: @@ -1000,11 +995,6 @@ def _unsubscribe(state, callback): break -def _unsubscribe_all(state): - with state.lock: - del state.callbacks_and_connectivities[:] - - def _augment_options(base_options, compression): compression_option = _compression.create_channel_option(compression) return tuple(base_options) + compression_option + (( @@ -1071,16 +1061,21 @@ class Channel(grpc.Channel): self._channel, _channel_managed_call_management(self._call_state), _common.encode(method), request_serializer, response_deserializer) + def _unsubscribe_all(self): + state = self._connectivity_state + if state: + with state.lock: + del state.callbacks_and_connectivities[:] + def _close(self): - _unsubscribe_all(self._connectivity_state) + self._unsubscribe_all() self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') cygrpc.fork_unregister_channel(self) - _moot(self._connectivity_state) def _close_on_fork(self): + self._unsubscribe_all() self._channel.close_on_fork(cygrpc.StatusCode.cancelled, 'Channel closed due to fork') - _moot(self._connectivity_state) def __enter__(self): return self @@ -1102,7 +1097,9 @@ class Channel(grpc.Channel): # for as long as they are in use and to close them after using them, # then deletion of this grpc._channel.Channel instance can be made to # effect closure of the underlying cygrpc.Channel instance. - # This prevent the failed-at-initializing object removal from failing. - # Though the __init__ failed, the removal will still trigger __del__. - if _moot is not None and hasattr(self, '_connectivity_state'): - _moot(self._connectivity_state) + try: + self._unsubscribe_all() + except: + # Exceptions in __del__ are ignored by Python anyway, but they can + # keep spamming logs. Just silence them. + pass From 6ed651356d6d77d61d9d933444b7784d85e399f4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 7 Jun 2019 16:28:31 -0700 Subject: [PATCH 283/676] Fix typo --- src/cpp/client/channel_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index f0aa8e4017a..de0f4e1787b 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -144,7 +144,7 @@ void ChannelResetConnectionBackoff(Channel* channel) { // ClientRpcInfo should be set before call because set_call also checks // whether the call has been cancelled, and if the call was cancelled, we - // should notify the interceptors too/ + // should notify the interceptors too. auto* info = context->set_client_rpc_info(method.name(), method.method_type(), this, interceptor_creators_, interceptor_pos); From 5bd4c0c7d069611d485bcbcff50c713d751e95c5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 7 Jun 2019 17:39:08 -0700 Subject: [PATCH 284/676] Add operator== for ServerAddress and InlinedVector --- .../filters/client_channel/server_address.cc | 10 ++++------ .../filters/client_channel/server_address.h | 4 +--- src/core/lib/gprpp/inlined_vector.h | 8 ++++++++ test/core/gprpp/inlined_vector_test.cc | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc index c2941afbcfd..31c0edaca17 100644 --- a/src/core/ext/filters/client_channel/server_address.cc +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -39,12 +39,10 @@ ServerAddress::ServerAddress(const void* address, size_t address_len, address_.len = static_cast(address_len); } -int ServerAddress::Cmp(const ServerAddress& other) const { - if (address_.len > other.address_.len) return 1; - if (address_.len < other.address_.len) return -1; - int retval = memcmp(address_.addr, other.address_.addr, address_.len); - if (retval != 0) return retval; - return grpc_channel_args_compare(args_, other.args_); +bool ServerAddress::operator==(const grpc_core::ServerAddress& other) const { + return address_.len == other.address_.len && + memcmp(address_.addr, other.address_.addr, address_.len) == 0 && + grpc_channel_args_compare(args_, other.args_) == 0; } bool ServerAddress::IsBalancer() const { diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h index 040cd2ee317..1b68a59ed85 100644 --- a/src/core/ext/filters/client_channel/server_address.h +++ b/src/core/ext/filters/client_channel/server_address.h @@ -73,9 +73,7 @@ class ServerAddress { return *this; } - bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } - - int Cmp(const ServerAddress& other) const; + bool operator==(const ServerAddress& other) const; const grpc_resolved_address& address() const { return address_; } const grpc_channel_args* args() const { return args_; } diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h index 66dc751a567..ffc37387ec3 100644 --- a/src/core/lib/gprpp/inlined_vector.h +++ b/src/core/lib/gprpp/inlined_vector.h @@ -97,6 +97,14 @@ class InlinedVector { return data()[offset]; } + bool operator==(const InlinedVector& other) const { + if (size_ != other.size_) return false; + for (size_t i = 0; i < size_; ++i) { + if (data()[i] != other.data()[i]) return false; + } + return true; + } + void reserve(size_t capacity) { if (capacity > capacity_) { T* new_dynamic = static_cast(gpr_malloc(sizeof(T) * capacity)); diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc index f943128f53c..4b7e46761c0 100644 --- a/test/core/gprpp/inlined_vector_test.cc +++ b/test/core/gprpp/inlined_vector_test.cc @@ -109,6 +109,24 @@ TEST(InlinedVectorTest, ConstIndexOperator) { const_func(v); } +TEST(InlinedVectorTest, EqualOperator) { + constexpr int kNumElements = 10; + // Both v1 and v2 are empty. + InlinedVector v1; + InlinedVector v2; + EXPECT_TRUE(v1 == v2); + // Both v1 and v2 contains the same data. + FillVector(&v1, kNumElements); + FillVector(&v2, kNumElements); + EXPECT_TRUE(v1 == v2); + // The sizes of v1 and v2 are different. + v1.push_back(0); + EXPECT_FALSE(v1 == v2); + // The contents of v1 and v2 are different although their sizes are the same. + v2.push_back(1); + EXPECT_FALSE(v1 == v2); +} + // the following constants and typedefs are used for copy/move // construction/assignment const size_t kInlinedLength = 8; From cbf70f2db208f97589aeb7d35707c9db33a056e7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 7 Jun 2019 17:40:56 -0700 Subject: [PATCH 285/676] Remove unneeded import --- src/objective-c/tests/InteropTests/InteropTests.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 4bdacbe4fa8..91e133a1300 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -18,8 +18,6 @@ #import "InteropTests.h" -#import - #include #ifdef GRPC_COMPILE_WITH_CRONET From 0d6cffd6c4bef4dc03108c93b29c03c89a99bfed Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 7 Jun 2019 10:40:04 -0400 Subject: [PATCH 286/676] Introduce grpc_slice_from_moved_string. Suggested by @markdroth to avoid extra allocation and copy when it's not needed. --- .../transport/chttp2/transport/frame_data.cc | 10 ++-- .../chttp2/transport/frame_rst_stream.cc | 5 +- src/core/lib/http/httpcli.cc | 6 +- src/core/lib/slice/slice.cc | 55 ++++++++++++++++--- src/core/lib/slice/slice_internal.h | 3 + src/core/lib/surface/validate_metadata.cc | 5 +- test/core/slice/slice_test.cc | 30 ++++++++++ 7 files changed, 95 insertions(+), 19 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 3734c0150b7..c50d7e48d41 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -109,7 +109,6 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( end = GRPC_SLICE_END_PTR(*slice); cur = beg; uint32_t message_flags; - char* msg; if (cur == end) { grpc_slice_buffer_remove_first(slices); @@ -132,15 +131,16 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->is_frame_compressed = true; /* GPR_TRUE */ break; default: + char* msg; gpr_asprintf(&msg, "Bad GRPC frame type 0x%02x", p->frame_type); p->error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - msg = grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); - p->error = grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_copied_string(msg)); - gpr_free(msg); + p->error = grpc_error_set_str( + p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_moved_string(grpc_core::UniquePtr( + grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)))); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc index ccde36cbc48..cda09c3dea1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc @@ -26,6 +26,7 @@ #include #include "src/core/ext/transport/chttp2/transport/frame.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/transport/http2_errors.h" grpc_slice grpc_chttp2_rst_stream_create(uint32_t id, uint32_t code, @@ -102,9 +103,9 @@ grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, error = grpc_error_set_int( grpc_error_set_str(GRPC_ERROR_CREATE_FROM_STATIC_STRING("RST_STREAM"), GRPC_ERROR_STR_GRPC_MESSAGE, - grpc_slice_from_copied_string(message)), + grpc_slice_from_moved_string( + grpc_core::UniquePtr(message))), GRPC_ERROR_INT_HTTP2_ERROR, static_cast(reason)); - gpr_free(message); } grpc_chttp2_mark_stream_closed(t, s, true, true, error); } diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 8a8da8b1604..93bb1432b16 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -28,6 +28,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/http/format_request.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/endpoint.h" @@ -112,12 +113,11 @@ static void append_error(internal_request* req, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Failed HTTP/1 client request"); } grpc_resolved_address* addr = &req->addresses->addrs[req->next_address - 1]; - char* addr_text = grpc_sockaddr_to_uri(addr); + grpc_core::UniquePtr addr_text(grpc_sockaddr_to_uri(addr)); req->overall_error = grpc_error_add_child( req->overall_error, grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, - grpc_slice_from_copied_string(addr_text))); - gpr_free(addr_text); + grpc_slice_from_moved_string(std::move(addr_text)))); } static void do_read(internal_request* req) { diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 566ad94d705..0f8ea6ae018 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -102,18 +102,19 @@ class NewSliceRefcount { } NewSliceRefcount(void (*destroy)(void*), void* user_data) - : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_), user_destroy_(destroy), user_data_(user_data) {} GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - grpc_slice_refcount* base_refcount() { return &rc_; } + grpc_slice_refcount* base_refcount() { return &base_; } private: ~NewSliceRefcount() { user_destroy_(user_data_); } - grpc_slice_refcount rc_; + grpc_slice_refcount base_; RefCount refs_; void (*user_destroy_)(void*); void* user_data_; @@ -141,7 +142,6 @@ grpc_slice grpc_slice_new(void* p, size_t len, void (*destroy)(void*)) { namespace grpc_core { /* grpc_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ - class NewWithLenSliceRefcount { public: static void Destroy(void* arg) { @@ -150,25 +150,48 @@ class NewWithLenSliceRefcount { NewWithLenSliceRefcount(void (*destroy)(void*, size_t), void* user_data, size_t user_length) - : rc_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, &rc_), + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_), user_data_(user_data), user_length_(user_length), user_destroy_(destroy) {} GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - grpc_slice_refcount* base_refcount() { return &rc_; } + grpc_slice_refcount* base_refcount() { return &base_; } private: ~NewWithLenSliceRefcount() { user_destroy_(user_data_, user_length_); } - grpc_slice_refcount rc_; + grpc_slice_refcount base_; RefCount refs_; void* user_data_; size_t user_length_; void (*user_destroy_)(void*, size_t); }; +/** grpc_slice_from_moved_(string|buffer) ref count .*/ +class MovedStringSliceRefCount { + public: + MovedStringSliceRefCount(grpc_core::UniquePtr&& str) + : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, + &base_), + str_(std::move(str)) {} + + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + + grpc_slice_refcount* base_refcount() { return &base_; } + + private: + static void Destroy(void* arg) { + Delete(static_cast(arg)); + } + + grpc_slice_refcount base_; + grpc_core::RefCount refs_; + grpc_core::UniquePtr str_; +}; + } // namespace grpc_core grpc_slice grpc_slice_new_with_len(void* p, size_t len, @@ -193,6 +216,24 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { return grpc_slice_from_copied_buffer(source, strlen(source)); } +grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p) { + const size_t len = strlen(p.get()); + uint8_t* ptr = reinterpret_cast(p.get()); + grpc_slice slice; + if (len <= sizeof(slice.data.inlined.bytes)) { + slice.refcount = nullptr; + slice.data.inlined.length = len; + memcpy(GRPC_SLICE_START_PTR(slice), ptr, len); + } else { + slice.refcount = + grpc_core::New(std::move(p)) + ->base_refcount(); + slice.data.refcounted.bytes = ptr; + slice.data.refcounted.length = len; + } + return slice; +} + namespace { class MallocRefCount { diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 23a2f6b81bc..457b76700ed 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -28,6 +28,7 @@ #include #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/transport/static_metadata.h" @@ -302,6 +303,8 @@ inline uint32_t grpc_slice_hash_internal(const grpc_slice& s) { : grpc_slice_hash_refcounted(s); } +grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p); + // Returns the memory used by this slice, not counting the slice structure // itself. This means that inlined and slices from static strings will return // 0. All other slices will return the size of the allocated chars. diff --git a/src/core/lib/surface/validate_metadata.cc b/src/core/lib/surface/validate_metadata.cc index a92ab823a38..46554596235 100644 --- a/src/core/lib/surface/validate_metadata.cc +++ b/src/core/lib/surface/validate_metadata.cc @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -44,8 +45,8 @@ static grpc_error* conforms_to(const grpc_slice& slice, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc), GRPC_ERROR_INT_OFFSET, p - GRPC_SLICE_START_PTR(slice)), - GRPC_ERROR_STR_RAW_BYTES, grpc_slice_from_copied_string(dump)); - gpr_free(dump); + GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_moved_string(grpc_core::UniquePtr(dump))); return error; } } diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index 6ed02366fe2..3c9c0572a43 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -27,6 +27,7 @@ #include #include +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" #include "test/core/util/test_config.h" @@ -285,6 +286,34 @@ static void test_static_slice_copy_interning(void) { grpc_shutdown(); } +static void test_moved_string_slice(void) { + LOG_TEST_NAME("test_moved_string_slice"); + + grpc_init(); + + // Small string should be inlined. + constexpr char kSmallStr[] = "hello12345"; + char* small_ptr = strdup(kSmallStr); + grpc_slice small = + grpc_slice_from_moved_string(grpc_core::UniquePtr(small_ptr)); + GPR_ASSERT(GRPC_SLICE_LENGTH(small) == strlen(kSmallStr)); + GPR_ASSERT(GRPC_SLICE_START_PTR(small) != + reinterpret_cast(small_ptr)); + grpc_slice_unref(small); + + // Large string should be move the reference. + constexpr char kSLargeStr[] = "hello123456789123456789123456789"; + char* large_ptr = strdup(kSLargeStr); + grpc_slice large = + grpc_slice_from_moved_string(grpc_core::UniquePtr(large_ptr)); + GPR_ASSERT(GRPC_SLICE_LENGTH(large) == strlen(kSLargeStr)); + GPR_ASSERT(GRPC_SLICE_START_PTR(large) == + reinterpret_cast(large_ptr)); + grpc_slice_unref(large); + + grpc_shutdown(); +} + int main(int argc, char** argv) { unsigned length; grpc::testing::TestEnvironment env(argc, argv); @@ -302,6 +331,7 @@ int main(int argc, char** argv) { test_slice_interning(); test_static_slice_interning(); test_static_slice_copy_interning(); + test_moved_string_slice(); grpc_shutdown(); return 0; } From a5090c5875af64b2ebe1883604c31ee1d4040463 Mon Sep 17 00:00:00 2001 From: Jonas Vautherin Date: Sat, 8 Jun 2019 17:50:55 +0200 Subject: [PATCH 287/676] Add support for CMAKE_SYSTEM_NAME=iOS An iOS toolchain is now part of CMake (3.14+), and therefore it makes sense to consider it. Note: it used to report "Darwin" and now it reports "iOS". Reference: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-or-watchos --- CMakeLists.txt | 6 ++++-- templates/CMakeLists.txt.template | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9d2168b8de..e78df7d8d40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,8 @@ if(UNIX) set(_gRPC_PLATFORM_LINUX ON) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_gRPC_PLATFORM_MAC ON) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "iOS") + set(_gRPC_PLATFORM_IOS ON) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android") set(_gRPC_PLATFORM_ANDROID ON) else() @@ -124,7 +126,7 @@ if(gRPC_BACKWARDS_COMPATIBILITY_MODE) endif() endif() -if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) +if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) # C core has C++ source code, but should not depend on libstc++ (for better portability). # We need to use a few tricks to convince cmake to do that. # https://stackoverflow.com/questions/15058403/how-to-stop-cmake-from-linking-against-libstdc @@ -149,7 +151,7 @@ if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() -if(_gRPC_PLATFORM_MAC) +if(_gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m pthread) elseif(_gRPC_PLATFORM_ANDROID) set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 4057da40c16..43bc063aee5 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -130,6 +130,8 @@ set(_gRPC_PLATFORM_LINUX ON) elseif(<%text>${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(_gRPC_PLATFORM_MAC ON) + elseif(<%text>${CMAKE_SYSTEM_NAME} MATCHES "iOS") + set(_gRPC_PLATFORM_IOS ON) elseif(<%text>${CMAKE_SYSTEM_NAME} MATCHES "Android") set(_gRPC_PLATFORM_ANDROID ON) else() @@ -173,7 +175,7 @@ endif() endif() - if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) + if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) # C core has C++ source code, but should not depend on libstc++ (for better portability). # We need to use a few tricks to convince cmake to do that. # https://stackoverflow.com/questions/15058403/how-to-stop-cmake-from-linking-against-libstdc @@ -198,7 +200,7 @@ set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS} -std=c++11") endif() - if(_gRPC_PLATFORM_MAC) + if(_gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_IOS) set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS} m pthread) elseif(_gRPC_PLATFORM_ANDROID) set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS} m) From 7b239a287e93ad9e0b4f3933b80921c03e5364c2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Jun 2019 10:29:42 -0700 Subject: [PATCH 288/676] Move extra args into RUN_TESTS_FLAGS --- tools/internal_ci/macos/grpc_basictests_objc.cfg | 7 +------ tools/internal_ci/macos/grpc_buildtests_objc.cfg | 7 +------ tools/internal_ci/macos/grpc_mactests_objc.cfg | 7 +------ tools/run_tests/run_tests_matrix.py | 9 ++++++++- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/tools/internal_ci/macos/grpc_basictests_objc.cfg b/tools/internal_ci/macos/grpc_basictests_objc.cfg index 6563fa69d02..c5ee5015c3c 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc.cfg @@ -27,10 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" -} - -env_vars { - key: "GRPC_OBJC_TEST_EXTRA_ARGS" - value: "-r ios-test-.*" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-test-.*'" } diff --git a/tools/internal_ci/macos/grpc_buildtests_objc.cfg b/tools/internal_ci/macos/grpc_buildtests_objc.cfg index d1a802eef5e..d4bbcf5ab47 100644 --- a/tools/internal_ci/macos/grpc_buildtests_objc.cfg +++ b/tools/internal_ci/macos/grpc_buildtests_objc.cfg @@ -27,10 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" -} - -env_vars { - key: "GRPC_OBJC_TEST_EXTRA_ARGS" - value: "-r ios-buildtest-.*" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-buildtest-.*'" } diff --git a/tools/internal_ci/macos/grpc_mactests_objc.cfg b/tools/internal_ci/macos/grpc_mactests_objc.cfg index 945bcb8c466..2147e12eb85 100644 --- a/tools/internal_ci/macos/grpc_mactests_objc.cfg +++ b/tools/internal_ci/macos/grpc_mactests_objc.cfg @@ -27,10 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" -} - -env_vars { - key: "GRPC_OBJC_TEST_EXTRA_ARGS" - value: "-r mac-test-.*" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r mac-test-.*'" } diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index ac9acbce730..ffb7e2cc71d 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -249,7 +249,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): configs=['dbg'], platforms=['macos'], labels=['basictests', 'multilang'], - extra_args=extra_args + [os.getenv('GRPC_OBJC_TEST_EXTRA_ARGS', '.*')], + extra_args=extra_args, inner_jobs=inner_jobs, timeout_seconds=_OBJC_RUNTESTS_TIMEOUT) @@ -519,6 +519,11 @@ if __name__ == "__main__": type=str, nargs='?', help='Upload test results to a specified BQ table.') + argp.add_argument( + '--extra_args', + default='', + type=str, + help='Extra test args passed to each sub-script.') args = argp.parse_args() extra_args = [] @@ -536,6 +541,8 @@ if __name__ == "__main__": extra_args.append('--bq_result_table') extra_args.append('%s' % args.bq_result_table) extra_args.append('--measure_cpu_costs') + if args.extra_args: + extra_args.append('%s' % args.extra_args) all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \ _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) From 29c3d437524d4b21379be2bbad52c476cbe9d673 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 9 Jun 2019 10:30:03 -0700 Subject: [PATCH 289/676] Make same change to pull request configs --- ..._objc_dbg.cfg => grpc_basictests_objc.cfg} | 2 +- .../pull_request/grpc_buildtests_objc.cfg | 31 +++++++++++++++++++ ...ts_objc_opt.cfg => grpc_mactests_objc.cfg} | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) rename tools/internal_ci/macos/pull_request/{grpc_basictests_objc_dbg.cfg => grpc_basictests_objc.cfg} (96%) create mode 100644 tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg rename tools/internal_ci/macos/pull_request/{grpc_basictests_objc_opt.cfg => grpc_mactests_objc.cfg} (90%) diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_dbg.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg similarity index 96% rename from tools/internal_ci/macos/pull_request/grpc_basictests_objc_dbg.cfg rename to tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg index 775fd355a5b..cb433413504 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_dbg.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --max_time=3600" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-test-.*'" } diff --git a/tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg b/tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg new file mode 100644 index 00000000000..8f35fda899a --- /dev/null +++ b/tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg @@ -0,0 +1,31 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 120 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-buildtest-.*'" +} diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_opt.cfg b/tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg similarity index 90% rename from tools/internal_ci/macos/pull_request/grpc_basictests_objc_opt.cfg rename to tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg index 652ef1bb77a..5691375392e 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_opt.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --max_time=3600" + value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r mac-test-.*'" } From 9b3c9e3635a360bfe2b7bd8b09e787b5d8f73d11 Mon Sep 17 00:00:00 2001 From: John Luo Date: Sun, 9 Jun 2019 22:31:36 -0700 Subject: [PATCH 290/676] Add MSBuild metadata to set LiteClient for client generation. --- src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index dd01b8183db..493212fe7e5 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -38,6 +38,7 @@ <_GrpcOutputOptions>%(Protobuf_Compile._GrpcOutputOptions);no_server + <_GrpcOutputOptions Condition=" '%(Protobuf_Compile.ClientType)' == 'LiteClient' ">%(Protobuf_Compile._GrpcOutputOptions);lite_client <_GrpcOutputOptions>%(Protobuf_Compile._GrpcOutputOptions);no_client From c9d928f36d1e497b9911ad5ff1b529b09e810295 Mon Sep 17 00:00:00 2001 From: John Luo Date: Mon, 10 Jun 2019 01:01:30 -0700 Subject: [PATCH 291/676] Migrate types required for client interceptors to Grpc.Core.Api --- .../Interceptors/CallInvokerExtensions.cs | 0 .../Interceptors/InterceptingCallInvoker.cs | 0 src/csharp/Grpc.Core/ForwardedTypes.cs | 2 ++ 3 files changed, 2 insertions(+) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/CallInvokerExtensions.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/InterceptingCallInvoker.cs (100%) diff --git a/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs b/src/csharp/Grpc.Core.Api/Interceptors/CallInvokerExtensions.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs rename to src/csharp/Grpc.Core.Api/Interceptors/CallInvokerExtensions.cs diff --git a/src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core.Api/Interceptors/InterceptingCallInvoker.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs rename to src/csharp/Grpc.Core.Api/Interceptors/InterceptingCallInvoker.cs diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index ab5f5a87c67..fb99cfc018d 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -36,6 +36,7 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(CallCredentials))] [assembly:TypeForwardedToAttribute(typeof(CallFlags))] [assembly:TypeForwardedToAttribute(typeof(CallInvoker))] +[assembly:TypeForwardedToAttribute(typeof(CallInvokerExtensions))] [assembly:TypeForwardedToAttribute(typeof(CallOptions))] [assembly:TypeForwardedToAttribute(typeof(ClientInterceptorContext<,>))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] @@ -45,6 +46,7 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(IAsyncStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(IClientStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(Interceptor))] +[assembly:TypeForwardedToAttribute(typeof(InterceptingCallInvoker))] [assembly:TypeForwardedToAttribute(typeof(IServerStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(Marshaller<>))] [assembly:TypeForwardedToAttribute(typeof(Marshallers))] From 5d65a9fa7b9cd0111a67c91f4ce3cc6fbd25a5d0 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 10 Jun 2019 15:07:39 -0400 Subject: [PATCH 292/676] Address comments from Vijay. --- src/core/ext/transport/chttp2/transport/frame_data.cc | 8 ++++---- src/core/lib/gpr/string.cc | 9 ++++++++- src/core/lib/gpr/string.h | 7 ++++++- src/core/lib/slice/slice.cc | 9 +++++++-- src/core/lib/slice/slice_internal.h | 2 ++ src/core/lib/slice/slice_string_helpers.cc | 9 +++++++++ src/core/lib/slice/slice_string_helpers.h | 2 ++ src/core/lib/surface/validate_metadata.cc | 3 +-- test/core/slice/slice_test.cc | 10 ++++++++++ 9 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index c50d7e48d41..74c305b820f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - p->error = grpc_error_set_str( - p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_moved_string(grpc_core::UniquePtr( - grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)))); + p->error = + grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_dump_slice_to_slice( + *slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index 31d5fdee5be..a39f56ef926 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -126,7 +126,8 @@ static void asciidump(dump_out* out, const char* buf, size_t len) { } } -char* gpr_dump(const char* buf, size_t len, uint32_t flags) { +char* gpr_dump_return_len(const char* buf, size_t len, uint32_t flags, + size_t* out_len) { dump_out out = dump_out_create(); if (flags & GPR_DUMP_HEX) { hexdump(&out, buf, len); @@ -135,9 +136,15 @@ char* gpr_dump(const char* buf, size_t len, uint32_t flags) { asciidump(&out, buf, len); } dump_out_append(&out, 0); + *out_len = out.length; return out.data; } +char* gpr_dump(const char* buf, size_t len, uint32_t flags) { + size_t unused; + return gpr_dump_return_len(buf, len, flags, &unused); +} + int gpr_parse_bytes_to_uint32(const char* buf, size_t len, uint32_t* result) { uint32_t out = 0; uint32_t new_val; diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index c5efcec3bb1..bf59db7abfe 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -32,9 +32,14 @@ #define GPR_DUMP_HEX 0x00000001 #define GPR_DUMP_ASCII 0x00000002 -/* Converts array buf, of length len, into a C string according to the flags. +/* Converts array buf, of length len, into a C string according to the flags. Result should be freed with gpr_free() */ char* gpr_dump(const char* buf, size_t len, uint32_t flags); +/* Converts array buf, of length len, into a C string according to the flags. + The length of the returned buffer is stored in out_len. + Result should be freed with gpr_free() */ +char* gpr_dump_return_len(const char* buf, size_t len, uint32_t flags, + size_t* out_len); /* Parses an array of bytes into an integer (base 10). Returns 1 on success, 0 on failure. */ diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 0f8ea6ae018..eebf66bb882 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -216,8 +216,8 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { return grpc_slice_from_copied_buffer(source, strlen(source)); } -grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p) { - const size_t len = strlen(p.get()); +grpc_slice grpc_slice_from_moved_buffer(grpc_core::UniquePtr p, + size_t len) { uint8_t* ptr = reinterpret_cast(p.get()); grpc_slice slice; if (len <= sizeof(slice.data.inlined.bytes)) { @@ -234,6 +234,11 @@ grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p) { return slice; } +grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p) { + const size_t len = strlen(p.get()); + return grpc_slice_from_moved_buffer(std::move(p), len); +} + namespace { class MallocRefCount { diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 457b76700ed..c6943fe6563 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -303,6 +303,8 @@ inline uint32_t grpc_slice_hash_internal(const grpc_slice& s) { : grpc_slice_hash_refcounted(s); } +grpc_slice grpc_slice_from_moved_buffer(grpc_core::UniquePtr p, + size_t len); grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p); // Returns the memory used by this slice, not counting the slice structure diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc index c2392fd392f..7887e0305fb 100644 --- a/src/core/lib/slice/slice_string_helpers.cc +++ b/src/core/lib/slice/slice_string_helpers.cc @@ -25,6 +25,7 @@ #include #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/slice/slice_internal.h" char* grpc_dump_slice(const grpc_slice& s, uint32_t flags) { @@ -32,6 +33,14 @@ char* grpc_dump_slice(const grpc_slice& s, uint32_t flags) { GRPC_SLICE_LENGTH(s), flags); } +grpc_slice grpc_dump_slice_to_slice(const grpc_slice& s, uint32_t flags) { + size_t len; + grpc_core::UniquePtr ptr( + gpr_dump_return_len(reinterpret_cast GRPC_SLICE_START_PTR(s), + GRPC_SLICE_LENGTH(s), flags, &len)); + return grpc_slice_from_moved_buffer(std::move(ptr), len); +} + /** Finds the initial (\a begin) and final (\a end) offsets of the next * substring from \a str + \a read_offset until the next \a sep or the end of \a * str. diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h index cb1df658fa5..6551a6df75d 100644 --- a/src/core/lib/slice/slice_string_helpers.h +++ b/src/core/lib/slice/slice_string_helpers.h @@ -31,6 +31,8 @@ /* Calls gpr_dump on a slice. */ char* grpc_dump_slice(const grpc_slice& slice, uint32_t flags); +/* Calls gpr_dump on a slice and returns the result as a slice. */ +grpc_slice grpc_dump_slice_to_slice(const grpc_slice& slice, uint32_t flags); /** Split \a str by the separator \a sep. Results are stored in \a dst, which * should be a properly initialized instance. */ diff --git a/src/core/lib/surface/validate_metadata.cc b/src/core/lib/surface/validate_metadata.cc index 46554596235..0f65091333d 100644 --- a/src/core/lib/surface/validate_metadata.cc +++ b/src/core/lib/surface/validate_metadata.cc @@ -40,13 +40,12 @@ static grpc_error* conforms_to(const grpc_slice& slice, int byte = idx / 8; int bit = idx % 8; if ((legal_bits[byte] & (1 << bit)) == 0) { - char* dump = grpc_dump_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); grpc_error* error = grpc_error_set_str( grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(err_desc), GRPC_ERROR_INT_OFFSET, p - GRPC_SLICE_START_PTR(slice)), GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_moved_string(grpc_core::UniquePtr(dump))); + grpc_dump_slice_to_slice(slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); return error; } } diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc index 3c9c0572a43..4f824cbd5ad 100644 --- a/test/core/slice/slice_test.cc +++ b/test/core/slice/slice_test.cc @@ -311,6 +311,16 @@ static void test_moved_string_slice(void) { reinterpret_cast(large_ptr)); grpc_slice_unref(large); + // Moved buffer must respect the provided length not the actual length of the + // string. + large_ptr = strdup(kSLargeStr); + small = grpc_slice_from_moved_buffer(grpc_core::UniquePtr(large_ptr), + strlen(kSmallStr)); + GPR_ASSERT(GRPC_SLICE_LENGTH(small) == strlen(kSmallStr)); + GPR_ASSERT(GRPC_SLICE_START_PTR(small) != + reinterpret_cast(large_ptr)); + grpc_slice_unref(small); + grpc_shutdown(); } From 31f0fad9a1fc09e26c3da9c6c4593efdd52a3775 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Jun 2019 13:32:59 -0700 Subject: [PATCH 293/676] Fix usage of new and delete --- src/core/lib/iomgr/cfstream_handle.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 2fda160f68a..b77851a6540 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -47,7 +47,8 @@ void CFStreamHandle::Release(void* info) { CFStreamHandle* CFStreamHandle::CreateStreamHandle( CFReadStreamRef read_stream, CFWriteStreamRef write_stream) { - return new CFStreamHandle(read_stream, write_stream); + CFStreamHandle* handle = static_cast(gpr_malloc(sizeof(CFStreamHandle))); + return new (handle) CFStreamHandle(read_stream, write_stream); } void CFStreamHandle::ReadCallback(CFReadStreamRef stream, @@ -188,7 +189,8 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { reason, val, val - 1); } if (gpr_unref(&refcount_)) { - delete this; + this->~CFStreamHandle(); + gpr_free(this); } } From 52291e5832f5876dc56a74b685a0e7fbb7b7eb65 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 10 Jun 2019 13:58:34 -0700 Subject: [PATCH 294/676] Fix PropogationOptions --- include/grpcpp/impl/codegen/client_context.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 8c3b669f2b7..02389464ce4 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -24,6 +24,7 @@ namespace grpc { typedef ::grpc_impl::ClientContext ClientContext; +typedef ::grpc_impl::PropagationOptions PropagationOptions; } // namespace grpc From a8fe8d4f19c0e563da47a90e9e3cada47ac779f6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Jun 2019 14:19:39 -0700 Subject: [PATCH 295/676] Use grpc_core::New and grpc_core::Delete --- src/core/lib/iomgr/cfstream_handle.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index b77851a6540..b56170cc49a 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -19,6 +19,7 @@ #include #include "src/core/lib/iomgr/port.h" +#include "src/core/lib/gprpp/memory.h" #ifdef GRPC_CFSTREAM #import @@ -47,8 +48,7 @@ void CFStreamHandle::Release(void* info) { CFStreamHandle* CFStreamHandle::CreateStreamHandle( CFReadStreamRef read_stream, CFWriteStreamRef write_stream) { - CFStreamHandle* handle = static_cast(gpr_malloc(sizeof(CFStreamHandle))); - return new (handle) CFStreamHandle(read_stream, write_stream); + return grpc_core::New(read_stream, write_stream); } void CFStreamHandle::ReadCallback(CFReadStreamRef stream, @@ -189,8 +189,7 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { reason, val, val - 1); } if (gpr_unref(&refcount_)) { - this->~CFStreamHandle(); - gpr_free(this); + grpc_core::Delete(this); } } From 8ff61a3b9c7e838950b47d20ab9c3dbcbab486da Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Jun 2019 14:24:53 -0700 Subject: [PATCH 296/676] clang-format --- src/core/lib/iomgr/cfstream_handle.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index b56170cc49a..8d01386a8f9 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -18,8 +18,8 @@ #include -#include "src/core/lib/iomgr/port.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/port.h" #ifdef GRPC_CFSTREAM #import From f7cb9c9f3e2d817a020585236d8b2f0264a120ee Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 10 Jun 2019 15:20:09 -0700 Subject: [PATCH 297/676] Add Debug Example --- examples/python/debug/BUILD.bazel | 59 ++++++++++++ examples/python/debug/README.md | 43 +++++++++ examples/python/debug/debug_server.py | 91 +++++++++++++++++++ examples/python/debug/get_stats.py | 52 +++++++++++ examples/python/debug/send_message.py | 67 ++++++++++++++ .../python/debug/test/_debug_example_test.py | 63 +++++++++++++ 6 files changed, 375 insertions(+) create mode 100644 examples/python/debug/BUILD.bazel create mode 100644 examples/python/debug/README.md create mode 100644 examples/python/debug/debug_server.py create mode 100644 examples/python/debug/get_stats.py create mode 100644 examples/python/debug/send_message.py create mode 100644 examples/python/debug/test/_debug_example_test.py diff --git a/examples/python/debug/BUILD.bazel b/examples/python/debug/BUILD.bazel new file mode 100644 index 00000000000..0134d8675ed --- /dev/null +++ b/examples/python/debug/BUILD.bazel @@ -0,0 +1,59 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_binary( + name = "debug_server", + testonly = 1, + srcs = ["debug_server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz", + "//examples:py_helloworld", + ], +) + +py_binary( + name = "send_message", + testonly = 1, + srcs = ["send_message.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], +) + +py_binary( + name = "get_stats", + testonly = 1, + srcs = ["get_stats.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz", + ], +) + +py_test( + name = "_debug_example_test", + srcs = ["test/_debug_example_test.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz", + "//examples:py_helloworld", + ":debug_server", + ":send_message", + ":get_stats", + ], +) \ No newline at end of file diff --git a/examples/python/debug/README.md b/examples/python/debug/README.md new file mode 100644 index 00000000000..db57c79de84 --- /dev/null +++ b/examples/python/debug/README.md @@ -0,0 +1,43 @@ +# gRPC Python Debug Example + +This example demonstrate the usage of Channelz. For a better looking website, the [gdebug](https://github.com/grpc/grpc-experiments/tree/master/gdebug) uses gRPC-Web protocol and will serve all useful information in web pages. + +## Channelz: Live Channel Tracing + +Channelz is a channel tracing feature. It will track statistics like how many messages have been sent, how many of them failed, what are the connected sockets. Since it is implemented in C-Core and has low-overhead, it is recommended to turn on for production services. See [Channelz design doc](https://github.com/grpc/proposal/blob/master/A14-channelz.md). + +## How to enable tracing log +The tracing log generation might have larger overhead, especially when you try to trace transport. It would result in replicating the traffic loads. However, it is still the most powerful tool when you need to dive in. + +### The Most Verbose Tracing Log + +Specify environment variables, then run your application: + +``` +GRPC_VERBOSITY=debug +GRPC_TRACE=all +``` + +For more granularity, please see [environment_variables](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md). + +### Debug Transport Protocol + +``` +GRPC_VERBOSITY=debug +GRPC_TRACE=tcp,http,secure_endpoint,transport_security +``` + +### Debug Connection Behavior + +``` +GRPC_VERBOSITY=debug +GRPC_TRACE=call_error,connectivity_state,pick_first,round_robin,glb +``` + +## How to debug your application? + +`pdb` is a debugging tool that is available for Python interpreters natively. You can set breakpoint, and execute commands while the application is stopped. + +The simplest usage is add a single line in the place you want to inspect: `import pdb; pdb.set_trace()`. When interpreter see this line, it would pop out a interactive command line interface for you to inspect the application state. + +For more detailed usage, see https://docs.python.org/3/library/pdb.html. diff --git a/examples/python/debug/debug_server.py b/examples/python/debug/debug_server.py new file mode 100644 index 00000000000..2866d284267 --- /dev/null +++ b/examples/python/debug/debug_server.py @@ -0,0 +1,91 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""The Python example of utilizing Channelz feature.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import logging +import time +from concurrent import futures +import random + +import grpc +from grpc_channelz.v1 import channelz + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 +_RANDOM_FAILURE_RATE = 0.3 + + +class FaultInjectGreeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self, failure_rate): + self._failure_rate = failure_rate + + def SayHello(self, request, context): + if random.random() < self._failure_rate: + context.abort(grpc.StatusCode.UNAVAILABLE, + 'Randomly injected failure.') + return helloworld_pb2.HelloReply( + message='Hello, %s!' % request.name) + + +def create_server(addr, failure_rate): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2_grpc.add_GreeterServicer_to_server( + FaultInjectGreeter(failure_rate), server) + + # Add Channelz Servicer to the gRPC server + channelz.add_channelz_servicer(server) + + server.add_insecure_port(addr) + return server + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--addr', + nargs=1, + type=str, + default='[::]:50051', + help='the address to listen on') + parser.add_argument( + '--failure_rate', + nargs=1, + type=float, + default=0.3, + help='a float indicates the percentage of failed message injections') + args = parser.parse_args() + + server = create_server(addr=args.addr, failure_rate=args.failure_rate) + server.start() + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(0) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + main() diff --git a/examples/python/debug/get_stats.py b/examples/python/debug/get_stats.py new file mode 100644 index 00000000000..22924098d51 --- /dev/null +++ b/examples/python/debug/get_stats.py @@ -0,0 +1,52 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Poll statistics from the server.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import logging +import argparse +import grpc +from grpc_channelz.v1 import channelz_pb2 +from grpc_channelz.v1 import channelz_pb2_grpc + + +def run(addr): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel(addr) as channel: + channelz_stub = channelz_pb2_grpc.ChannelzStub(channel) + response = channelz_stub.GetServers( + channelz_pb2.GetServersRequest(start_server_id=0)) + print('Info for all servers: %s' % response) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--addr', + nargs=1, + type=str, + default='[::]:50051', + help='the address to request') + args = parser.parse_args() + run(addr=args.addr) + + +if __name__ == '__main__': + logging.basicConfig() + main() diff --git a/examples/python/debug/send_message.py b/examples/python/debug/send_message.py new file mode 100644 index 00000000000..99425263b50 --- /dev/null +++ b/examples/python/debug/send_message.py @@ -0,0 +1,67 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Send multiple greeting messages to the backend.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import logging +import argparse +import grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + + +def process(stub, request): + try: + response = stub.SayHello(request) + except grpc.RpcError as rpc_error: + print('Received error: %s' % rpc_error) + else: + print('Received message: %s' % response) + + +def run(addr, n): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + with grpc.insecure_channel(addr) as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + request = helloworld_pb2.HelloRequest(name='you') + for _ in range(n): + process(stub, request) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--addr', + nargs=1, + type=str, + default='[::]:50051', + help='the address to request') + parser.add_argument( + '-n', + nargs=1, + type=int, + default=10, + help='an integer for number of messages to sent') + args = parser.parse_args() + run(addr=args.addr, n=args.n) + + +if __name__ == '__main__': + logging.basicConfig() + main() diff --git a/examples/python/debug/test/_debug_example_test.py b/examples/python/debug/test/_debug_example_test.py new file mode 100644 index 00000000000..133fee2b0b6 --- /dev/null +++ b/examples/python/debug/test/_debug_example_test.py @@ -0,0 +1,63 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test for gRPC Python debug example.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import logging +import unittest +from contextlib import contextmanager +import socket + +from examples.python.debug import debug_server +from examples.python.debug import send_message +from examples.python.debug import get_stats + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_FAILURE_RATE = 0.5 +_NUMBER_OF_MESSAGES = 100 + + +@contextmanager +def get_free_loopback_tcp_port(): + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + else: + tcp_socket = socket.socket(socket.AF_INET) + tcp_socket.bind(('', 0)) + address_tuple = tcp_socket.getsockname() + yield "localhost:%s" % (address_tuple[1]) + tcp_socket.close() + + +class DebugExampleTest(unittest.TestCase): + + def test_channelz_example(self): + with get_free_loopback_tcp_port() as addr: + server = debug_server.create_server( + addr=addr, failure_rate=_FAILURE_RATE) + server.start() + send_message.run(addr=addr, n=_NUMBER_OF_MESSAGES) + get_stats.run(addr=addr) + server.stop(None) + # No unhandled exception raised, test passed! + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From ea427791d398ec2198e543361c51c3f378786e48 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 10 Jun 2019 16:22:25 -0700 Subject: [PATCH 298/676] Reviewer comments --- test/core/bad_client/tests/unknown_frame.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc index a9f56548c2a..e58166ccd56 100644 --- a/test/core/bad_client/tests/unknown_frame.cc +++ b/test/core/bad_client/tests/unknown_frame.cc @@ -33,16 +33,18 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq, } } +#define APPEND_BUFFER(string, to_append) \ + ((string).append((to_append), sizeof(to_append) - 1)) + namespace { TEST(UnknownFrameType, Test) { /* test that all invalid/unknown frame types are handled */ for (int i = 10; i <= 255; i++) { std::string unknown_frame_string; - unknown_frame_string.append("\x00\x00\x00", sizeof("\x00\x00\x00") - 1); + APPEND_BUFFER(unknown_frame_string, "\x00\x00\x00"); char frame_type = static_cast(i); unknown_frame_string.append(&frame_type, 1); - unknown_frame_string.append("\x00\x00\x00\x00\x01", - sizeof("\x00\x00\x00\x00\x01") - 1); + APPEND_BUFFER(unknown_frame_string, "\x00\x00\x00\x00\x01"); grpc_bad_client_arg args[2]; args[0] = connection_preface_arg; args[1].client_validator = nullptr; From 9847c6364a48700ad633272799ade77530e7de54 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Mon, 10 Jun 2019 23:31:51 +0000 Subject: [PATCH 299/676] Silence pylint --- src/python/grpcio/grpc/_channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 4b761bfe5f8..24f928ef69f 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -1099,7 +1099,7 @@ class Channel(grpc.Channel): # effect closure of the underlying cygrpc.Channel instance. try: self._unsubscribe_all() - except: + except: # pylint: disable=bare-except # Exceptions in __del__ are ignored by Python anyway, but they can # keep spamming logs. Just silence them. pass From 4155e9cf05aa6af340695862de87456611b1ffa2 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 11 Jun 2019 18:02:00 +1200 Subject: [PATCH 300/676] React to renaming grpc-dotnet sln --- .../grpc_interop_aspnetcore/build_interop.sh.template | 2 +- .../interoptest/grpc_interop_aspnetcore/build_interop.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index 55ecfb30192..acf12579357 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -39,4 +39,4 @@ ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet fi - dotnet build --configuration Debug Grpc.AspNetCore.sln + dotnet build --configuration Debug Grpc.DotNet.sln diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 0b32638b54b..acb2a0ab2d9 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -37,4 +37,4 @@ then ln -s $(pwd)/.dotnet/dotnet /usr/local/bin/dotnet fi -dotnet build --configuration Debug Grpc.AspNetCore.sln +dotnet build --configuration Debug Grpc.DotNet.sln From a03cc2c8764d0031797749b5271fb41d3bb91290 Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Tue, 11 Jun 2019 10:11:55 -0700 Subject: [PATCH 301/676] Update ruby version to just 3.8 --- templates/grpc.gemspec.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index 9ca797fe913..f8dd0938936 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -31,7 +31,7 @@ s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.8.0' + s.add_dependency 'google-protobuf', '~> 3.8' s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' From 1f1eff115afc3aa95c6bf288e52490b893488426 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Jun 2019 11:57:37 -0700 Subject: [PATCH 302/676] Split extra arguments --- 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 ffb7e2cc71d..7de1cb975d3 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -542,7 +542,7 @@ if __name__ == "__main__": extra_args.append('%s' % args.bq_result_table) extra_args.append('--measure_cpu_costs') if args.extra_args: - extra_args.append('%s' % args.extra_args) + extra_args.extend(('%s' % args.extra_args).split()) all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \ _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) From 3931c0bcd28c97eb9e71caddf1ae26c171bed93c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 11 Jun 2019 11:57:58 -0700 Subject: [PATCH 303/676] yapf_codes --- tools/run_tests/run_tests.py | 140 ++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 66 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index d99bbf43ffa..26762aa4840 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1050,72 +1050,80 @@ class ObjCLanguage(object): def test_specs(self): out = [] if self.config == 'dbg': - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' - }) - out += job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample-frameworks', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', - 'FRAMEWORKS': 'YES' - }) - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-switftsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'SwiftSample', - 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_plugin_tests.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-plugintest', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=20 * 60, - shortname='ios-test-cfstream-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-unittests', - cpu_cost=1e6, - environ={SCHEME: 'UnitTests'}) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-interoptests', - cpu_cost=1e6, - environ={SCHEME: 'InteropTests'}) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-cronettests', - cpu_cost=1e6, - environ={SCHEME: 'CronetTests'}) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='mac-test-basictests', - cpu_cost=1e6, - environ={SCHEME: 'MacTests'}) - - return sorted(out); + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' + }) + out += job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample-frameworks', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', + 'FRAMEWORKS': 'YES' + }) + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-switftsample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'SwiftSample', + 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_plugin_tests.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-plugintest', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], + timeout_seconds=20 * 60, + shortname='ios-test-cfstream-tests', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-unittests', + cpu_cost=1e6, + environ={ + SCHEME: 'UnitTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-interoptests', + cpu_cost=1e6, + environ={ + SCHEME: 'InteropTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-cronettests', + cpu_cost=1e6, + environ={ + SCHEME: 'CronetTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='mac-test-basictests', + cpu_cost=1e6, + environ={ + SCHEME: 'MacTests' + }) + + return sorted(out) def pre_build_steps(self): return [] From 7f787bd08371066e616a4a784712b237f0bab7fa Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Tue, 11 Jun 2019 12:12:33 -0700 Subject: [PATCH 304/676] Link against pthread in examples --- examples/cpp/helloworld/Makefile | 2 ++ examples/cpp/route_guide/Makefile | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index 6af92347aa3..9af7337fd1b 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -21,10 +21,12 @@ CPPFLAGS += `pkg-config --cflags protobuf grpc` CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -pthread\ -lgrpc++_reflection\ -ldl else LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\ + -pthread\ -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ -ldl endif diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index 48a2073ba8c..3bf61cb76f1 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -21,10 +21,12 @@ CPPFLAGS += `pkg-config --cflags protobuf grpc` CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\ + -pthread\ -lgrpc++_reflection\ -ldl else LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\ + -pthread\ -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\ -ldl endif From 6a71e9f54635592506738ab0bd2d76e0d982eddc Mon Sep 17 00:00:00 2001 From: Hao Nguyen Date: Tue, 11 Jun 2019 13:17:41 -0700 Subject: [PATCH 305/676] Change Ruby Protobuf version to 3.8 --- grpc.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grpc.gemspec b/grpc.gemspec index 0f66332d48f..77b4f8c862e 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.8.0' + s.add_dependency 'google-protobuf', '~> 3.8' s.add_dependency 'googleapis-common-protos-types', '~> 1.0' s.add_development_dependency 'bundler', '~> 1.9' From bb5f186f3dd6e90872762260708a15dc399b8945 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 11 Jun 2019 16:27:55 -0400 Subject: [PATCH 306/676] Convert TraceFlags in the hot path to DebugTraceFlags. We see up to 4% of cpu reduction and 3% of latency savings in production benchmarks. --- src/core/lib/iomgr/call_combiner.cc | 2 +- src/core/lib/iomgr/call_combiner.h | 2 +- src/core/lib/iomgr/ev_posix.cc | 6 +++--- src/core/lib/iomgr/ev_posix.h | 5 +++-- src/core/lib/iomgr/ev_windows.cc | 4 ++-- src/core/lib/iomgr/lockfree_event.cc | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc index 6a4e85de4df..6530d1c6ce6 100644 --- a/src/core/lib/iomgr/call_combiner.cc +++ b/src/core/lib/iomgr/call_combiner.cc @@ -28,7 +28,7 @@ namespace grpc_core { -TraceFlag grpc_call_combiner_trace(false, "call_combiner"); +DebugOnlyTraceFlag grpc_call_combiner_trace(false, "call_combiner"); namespace { diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h index a10b437c15a..b56966f4196 100644 --- a/src/core/lib/iomgr/call_combiner.h +++ b/src/core/lib/iomgr/call_combiner.h @@ -43,7 +43,7 @@ namespace grpc_core { -extern TraceFlag grpc_call_combiner_trace; +extern DebugOnlyTraceFlag grpc_call_combiner_trace; class CallCombiner { public: diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index ddafb7b5539..92f81c2efb8 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -44,11 +44,11 @@ GPR_GLOBAL_CONFIG_DEFINE_STRING( "This is a comma-separated list of engines, which are tried in priority " "order first -> last.") -grpc_core::TraceFlag grpc_polling_trace(false, - "polling"); /* Disabled by default */ +grpc_core::DebugOnlyTraceFlag grpc_polling_trace( + false, "polling"); /* Disabled by default */ /* Traces fd create/close operations */ -grpc_core::TraceFlag grpc_fd_trace(false, "fd_trace"); +grpc_core::DebugOnlyTraceFlag grpc_fd_trace(false, "fd_trace"); grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount"); grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 30bb5e40faf..84edabce71e 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -32,8 +32,9 @@ GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_poll_strategy); -extern grpc_core::TraceFlag grpc_fd_trace; /* Disabled by default */ -extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */ +extern grpc_core::DebugOnlyTraceFlag grpc_fd_trace; /* Disabled by default */ +extern grpc_core::DebugOnlyTraceFlag + grpc_polling_trace; /* Disabled by default */ #define GRPC_FD_TRACE(format, ...) \ if (GRPC_TRACE_FLAG_ENABLED(grpc_fd_trace)) { \ diff --git a/src/core/lib/iomgr/ev_windows.cc b/src/core/lib/iomgr/ev_windows.cc index 32c62b7a762..e3f5715a873 100644 --- a/src/core/lib/iomgr/ev_windows.cc +++ b/src/core/lib/iomgr/ev_windows.cc @@ -24,7 +24,7 @@ #include "src/core/lib/debug/trace.h" -grpc_core::TraceFlag grpc_polling_trace(false, - "polling"); /* Disabled by default */ +grpc_core::DebugOnlyTraceFlag grpc_polling_trace( + false, "polling"); /* Disabled by default */ #endif // GRPC_WINSOCK_SOCKET diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc index f0c40b4827d..f33485ee59d 100644 --- a/src/core/lib/iomgr/lockfree_event.cc +++ b/src/core/lib/iomgr/lockfree_event.cc @@ -24,7 +24,7 @@ #include "src/core/lib/debug/trace.h" -extern grpc_core::TraceFlag grpc_polling_trace; +extern grpc_core::DebugOnlyTraceFlag grpc_polling_trace; /* 'state' holds the to call when the fd is readable or writable respectively. It can contain one of the following values: From a0adb5003ce6066b795009cc9f2d3abaca9180b7 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 11 Jun 2019 15:47:54 -0700 Subject: [PATCH 307/676] Feedbackg --- src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml | 11 +++++++++++ src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml index 66862582dad..dd220bf564d 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml @@ -26,5 +26,16 @@ + + + + + + + + diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index 493212fe7e5..bc78e340e33 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -38,11 +38,13 @@ <_GrpcOutputOptions>%(Protobuf_Compile._GrpcOutputOptions);no_server - <_GrpcOutputOptions Condition=" '%(Protobuf_Compile.ClientType)' == 'LiteClient' ">%(Protobuf_Compile._GrpcOutputOptions);lite_client <_GrpcOutputOptions>%(Protobuf_Compile._GrpcOutputOptions);no_client + + <_GrpcOutputOptions Condition=" '%(Protobuf_Compile.ClientBaseType)' == 'LiteClientBase' ">%(Protobuf_Compile._GrpcOutputOptions);lite_client + From 8438cc804ff44dae734e113bb2e59539a9d8ac8a Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Tue, 11 Jun 2019 17:00:32 -0700 Subject: [PATCH 308/676] Added debug and non-debug tracers for subchannel. --- doc/environment_variables.md | 2 ++ src/core/ext/filters/client_channel/subchannel.cc | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 778560d4273..6782f1ee6a6 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -74,6 +74,7 @@ some configuration as environment variables that can be set. - queue_pluck - server_channel - lightweight trace of significant server channel events - secure_endpoint - traces bytes flowing through encrypted channels + - subchannel - traces the connectivity state of subchannel - timer - timers (alarms) in the grpc internals - timer_check - more detailed trace of timer logic in grpc internals - transport_security - traces metadata about secure channel establishment @@ -89,6 +90,7 @@ some configuration as environment variables that can be set. - pending_tags - traces still-in-progress tags on completion queues - polling - traces the selected polling engine - polling_api - traces the api calls to polling engine + - subchannel_refcount - queue_refcount - error_refcount - stream_refcount diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index cc3457e1e96..dd16eded826 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -75,6 +75,9 @@ namespace grpc_core { +TraceFlag grpc_trace_subchannel(false, "subchannel"); +DebugOnlyTraceFlag grpc_trace_subchannel_refcount(false, "subchannel_refcount"); + // // ConnectedSubchannel // @@ -83,7 +86,7 @@ ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, RefCountedPtr channelz_subchannel, intptr_t socket_uuid) - : ConnectedSubchannelInterface(&grpc_trace_stream_refcount), + : ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount), channel_stack_(channel_stack), args_(grpc_channel_args_copy(args)), channelz_subchannel_(std::move(channelz_subchannel)), @@ -332,7 +335,7 @@ class Subchannel::ConnectedSubchannelStateWatcher { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: { if (!c->disconnected_ && c->connected_subchannel_ != nullptr) { - if (grpc_trace_stream_refcount.enabled()) { + if (grpc_trace_subchannel.enabled()) { gpr_log(GPR_INFO, "Connected subchannel %p of subchannel %p has gone into " "%s. Attempting to reconnect.", @@ -1106,7 +1109,7 @@ gpr_atm Subchannel::RefMutate( gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta) : gpr_atm_no_barrier_fetch_add(&ref_pair_, delta); #ifndef NDEBUG - if (grpc_trace_stream_refcount.enabled()) { + if (grpc_trace_subchannel_refcount.enabled()) { gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this, purpose, old_val, old_val + delta, reason); From 84d75d454ee2a0a7585281e56035022770975ccb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 11 Jun 2019 19:08:50 -0700 Subject: [PATCH 309/676] Move error ref to the the closure function instead of an internal function --- src/core/lib/security/transport/security_handshaker.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index fdc64727b96..3ad04774837 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -195,7 +195,7 @@ void SecurityHandshaker::HandshakeFailedLocked(grpc_error* error) { void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { MutexLock lock(&mu_); if (error != GRPC_ERROR_NONE || is_shutdown_) { - HandshakeFailedLocked(GRPC_ERROR_REF(error)); + HandshakeFailedLocked(error); return; } // Create zero-copy frame protector, if implemented. @@ -255,7 +255,7 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error* error) { RefCountedPtr(static_cast(arg)) - ->OnPeerCheckedInner(error); + ->OnPeerCheckedInner(GRPC_ERROR_REF(error)); } grpc_error* SecurityHandshaker::CheckPeerLocked() { From 7767fbe683fc95f562a6ae1a22c67828e80afebe Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 12 Jun 2019 06:44:36 -0700 Subject: [PATCH 310/676] Hide ConnectedSubchannel from LB policy API. --- .../filters/client_channel/client_channel.cc | 420 +++++++++++++----- .../ext/filters/client_channel/lb_policy.h | 2 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 9 +- .../lb_policy/pick_first/pick_first.cc | 30 +- .../lb_policy/round_robin/round_robin.cc | 20 +- .../lb_policy/subchannel_list.h | 126 ++---- .../client_channel/lb_policy/xds/xds.cc | 2 +- .../ext/filters/client_channel/subchannel.cc | 23 +- .../ext/filters/client_channel/subchannel.h | 71 ++- .../client_channel/subchannel_interface.h | 45 +- src/core/lib/gprpp/map.h | 28 ++ src/core/lib/transport/metadata.cc | 5 + test/core/gprpp/map_test.cc | 29 ++ test/core/util/test_lb_policies.cc | 2 +- 14 files changed, 514 insertions(+), 298 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 81562ab2107..19cceb6bf4f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -147,6 +147,9 @@ class ChannelData { return service_config_; } + RefCountedPtr GetConnectedSubchannelInDataPlane( + SubchannelInterface* subchannel) const; + grpc_connectivity_state CheckConnectivityState(bool try_to_connect); void AddExternalConnectivityWatcher(grpc_polling_entity pollent, grpc_connectivity_state* state, @@ -161,9 +164,9 @@ class ChannelData { } private: + class SubchannelWrapper; class ConnectivityStateAndPickerSetter; class ServiceConfigSetter; - class GrpcSubchannel; class ClientChannelControlHelper; class ExternalConnectivityWatcher { @@ -262,7 +265,14 @@ class ChannelData { UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; bool received_first_resolver_result_ = false; + // The number of SubchannelWrapper instances referencing a given Subchannel. Map subchannel_refcount_map_; + // Pending ConnectedSubchannel updates for each SubchannelWrapper. + // Updates are queued here in the control plane combiner and then applied + // in the data plane combiner when the picker is updated. + Map, RefCountedPtr, + RefCountedPtrLess> + pending_subchannel_updates_; // // Fields accessed from both data plane and control plane combiners. @@ -706,6 +716,247 @@ class CallData { grpc_metadata_batch send_trailing_metadata_; }; +// +// ChannelData::SubchannelWrapper +// + +// This class is a wrapper for Subchannel that hides details of the +// channel's implementation (such as the health check service name and +// connected subchannel) from the LB policy API. +// +// Note that no synchronization is needed here, because even if the +// underlying subchannel is shared between channels, this wrapper will only +// be used within one channel, so it will always be synchronized by the +// control plane combiner. +class ChannelData::SubchannelWrapper : public SubchannelInterface { + public: + SubchannelWrapper(ChannelData* chand, Subchannel* subchannel, + UniquePtr health_check_service_name) + : SubchannelInterface(&grpc_client_channel_routing_trace), + chand_(chand), + subchannel_(subchannel), + health_check_service_name_(std::move(health_check_service_name)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: creating subchannel wrapper %p for subchannel %p", + chand, this, subchannel_); + } + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper"); + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + if (it == chand_->subchannel_refcount_map_.end()) { + chand_->channelz_node_->AddChildSubchannel(subchannel_uuid); + it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first; + } + ++it->second; + } + } + + ~SubchannelWrapper() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: destroying subchannel wrapper %p for subchannel %p", + chand_, this, subchannel_); + } + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + GPR_ASSERT(it != chand_->subchannel_refcount_map_.end()); + --it->second; + if (it->second == 0) { + chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid); + chand_->subchannel_refcount_map_.erase(it); + } + } + GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "SubchannelWrapper"); + } + + grpc_connectivity_state CheckConnectivityState() override { + RefCountedPtr connected_subchannel; + grpc_connectivity_state connectivity_state = + subchannel_->CheckConnectivityState(health_check_service_name_.get(), + &connected_subchannel); + MaybeUpdateConnectedSubchannel(std::move(connected_subchannel)); + return connectivity_state; + } + + void WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr watcher) override { + auto& watcher_wrapper = watcher_map_[watcher.get()]; + GPR_ASSERT(watcher_wrapper == nullptr); + watcher_wrapper = New( + std::move(watcher), Ref(DEBUG_LOCATION, "WatcherWrapper")); + subchannel_->WatchConnectivityState( + initial_state, + UniquePtr(gpr_strdup(health_check_service_name_.get())), + OrphanablePtr( + watcher_wrapper)); + } + + void CancelConnectivityStateWatch( + ConnectivityStateWatcherInterface* watcher) override { + auto it = watcher_map_.find(watcher); + GPR_ASSERT(it != watcher_map_.end()); + subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(), + it->second); + watcher_map_.erase(it); + } + + void AttemptToConnect() override { subchannel_->AttemptToConnect(); } + + void ResetBackoff() override { subchannel_->ResetBackoff(); } + + const grpc_channel_args* channel_args() override { + return subchannel_->channel_args(); + } + + // Caller must be holding the control-plane combiner. + ConnectedSubchannel* connected_subchannel() const { + return connected_subchannel_.get(); + } + + // Caller must be holding the data-plane combiner. + ConnectedSubchannel* connected_subchannel_in_data_plane() const { + return connected_subchannel_in_data_plane_.get(); + } + void set_connected_subchannel_in_data_plane( + RefCountedPtr connected_subchannel) { + connected_subchannel_in_data_plane_ = std::move(connected_subchannel); + } + + private: + // Subchannel and SubchannelInterface have different interfaces for + // their respective ConnectivityStateWatcherInterface classes. + // The one in Subchannel updates the ConnectedSubchannel along with + // the state, whereas the one in SubchannelInterface does not expose + // the ConnectedSubchannel. + // + // This wrapper provides a bridge between the two. It implements + // Subchannel::ConnectivityStateWatcherInterface and wraps + // the instance of SubchannelInterface::ConnectivityStateWatcherInterface + // that was passed in by the LB policy. We pass an instance of this + // class to the underlying Subchannel, and when we get updates from + // the subchannel, we pass those on to the wrapped watcher to return + // the update to the LB policy. This allows us to set the connected + // subchannel before passing the result back to the LB policy. + class WatcherWrapper : public Subchannel::ConnectivityStateWatcherInterface { + public: + WatcherWrapper( + UniquePtr + watcher, + RefCountedPtr parent) + : watcher_(std::move(watcher)), parent_(std::move(parent)) {} + + ~WatcherWrapper() { parent_.reset(DEBUG_LOCATION, "WatcherWrapper"); } + + void Orphan() override { Unref(); } + + void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) override { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: connectivity change for subchannel wrapper %p " + "subchannel %p (connected_subchannel=%p state=%s); " + "hopping into combiner", + parent_->chand_, parent_.get(), parent_->subchannel_, + connected_subchannel.get(), + grpc_connectivity_state_name(new_state)); + } + // Will delete itself. + New(Ref(), new_state, std::move(connected_subchannel)); + } + + grpc_pollset_set* interested_parties() override { + return watcher_->interested_parties(); + } + + private: + class Updater { + public: + Updater(RefCountedPtr parent, + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) + : parent_(std::move(parent)), + state_(new_state), + connected_subchannel_(std::move(connected_subchannel)) { + GRPC_CLOSURE_INIT( + &closure_, ApplyUpdateInControlPlaneCombiner, this, + grpc_combiner_scheduler(parent_->parent_->chand_->combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); + } + + private: + static void ApplyUpdateInControlPlaneCombiner(void* arg, + grpc_error* error) { + Updater* self = static_cast(arg); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: processing connectivity change in combiner " + "for subchannel wrapper %p subchannel %p " + "(connected_subchannel=%p state=%s)", + self->parent_->parent_->chand_, self->parent_->parent_.get(), + self->parent_->parent_->subchannel_, + self->connected_subchannel_.get(), + grpc_connectivity_state_name(self->state_)); + } + self->parent_->parent_->MaybeUpdateConnectedSubchannel( + std::move(self->connected_subchannel_)); + self->parent_->watcher_->OnConnectivityStateChange(self->state_); + Delete(self); + } + + RefCountedPtr parent_; + grpc_connectivity_state state_; + RefCountedPtr connected_subchannel_; + grpc_closure closure_; + }; + + UniquePtr watcher_; + RefCountedPtr parent_; + }; + + void MaybeUpdateConnectedSubchannel( + RefCountedPtr connected_subchannel) { + // Update the connected subchannel only if the channel is not shutting + // down. This is because once the channel is shutting down, we + // ignore picker updates from the LB policy, which means that + // ConnectivityStateAndPickerSetter will never process the entries + // in chand_->pending_subchannel_updates_. So we don't want to add + // entries there that will never be processed, since that would + // leave dangling refs to the channel and prevent its destruction. + grpc_error* disconnect_error = chand_->disconnect_error(); + if (disconnect_error != GRPC_ERROR_NONE) return; + // Not shutting down, so do the update. + if (connected_subchannel_ != connected_subchannel) { + connected_subchannel_ = std::move(connected_subchannel); + // Record the new connected subchannel so that it can be updated + // in the data plane combiner the next time the picker is updated. + chand_->pending_subchannel_updates_[Ref( + DEBUG_LOCATION, "ConnectedSubchannelUpdate")] = connected_subchannel_; + } + } + + ChannelData* chand_; + Subchannel* subchannel_; + UniquePtr health_check_service_name_; + // Maps from the address of the watcher passed to us by the LB policy + // to the address of the WrapperWatcher that we passed to the underlying + // subchannel. This is needed so that when the LB policy calls + // CancelConnectivityStateWatch() with its watcher, we know the + // corresponding WrapperWatcher to cancel on the underlying subchannel. + Map watcher_map_; + // To be accessed only in the control plane combiner. + RefCountedPtr connected_subchannel_; + // To be accessed only in the data plane combiner. + RefCountedPtr connected_subchannel_in_data_plane_; +}; + // // ChannelData::ConnectivityStateAndPickerSetter // @@ -729,10 +980,13 @@ class ChannelData::ConnectivityStateAndPickerSetter { grpc_slice_from_static_string( GetChannelConnectivityStateChangeString(state))); } + // Grab any pending subchannel updates. + pending_subchannel_updates_ = + std::move(chand_->pending_subchannel_updates_); // Bounce into the data plane combiner to reset the picker. GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ConnectivityStateAndPickerSetter"); - GRPC_CLOSURE_INIT(&closure_, SetPicker, this, + GRPC_CLOSURE_INIT(&closure_, SetPickerInDataPlane, this, grpc_combiner_scheduler(chand->data_plane_combiner_)); GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); } @@ -755,16 +1009,38 @@ class ChannelData::ConnectivityStateAndPickerSetter { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } - static void SetPicker(void* arg, grpc_error* ignored) { + static void SetPickerInDataPlane(void* arg, grpc_error* ignored) { auto* self = static_cast(arg); - // Update picker. - self->chand_->picker_ = std::move(self->picker_); + // Handle subchannel updates. + for (auto& p : self->pending_subchannel_updates_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, + "chand=%p: updating subchannel wrapper %p data plane " + "connected_subchannel to %p", + self->chand_, p.first.get(), p.second.get()); + } + p.first->set_connected_subchannel_in_data_plane(std::move(p.second)); + } + // Swap out the picker. We hang on to the old picker so that it can + // be deleted in the control-plane combiner, since that's where we need + // to unref the subchannel wrappers that are reffed by the picker. + self->picker_.swap(self->chand_->picker_); // Re-process queued picks. for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr; pick = pick->next) { CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE); } - // Clean up. + // Pop back into the control plane combiner to delete ourself, so + // that we make sure to unref subchannel wrappers there. This + // includes both the ones reffed by the old picker (now stored in + // self->picker_) and the ones in self->pending_subchannel_updates_. + GRPC_CLOSURE_INIT(&self->closure_, CleanUpInControlPlane, self, + grpc_combiner_scheduler(self->chand_->combiner_)); + GRPC_CLOSURE_SCHED(&self->closure_, GRPC_ERROR_NONE); + } + + static void CleanUpInControlPlane(void* arg, grpc_error* ignored) { + auto* self = static_cast(arg); GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, "ConnectivityStateAndPickerSetter"); Delete(self); @@ -772,6 +1048,9 @@ class ChannelData::ConnectivityStateAndPickerSetter { ChannelData* chand_; UniquePtr picker_; + Map, RefCountedPtr, + RefCountedPtrLess> + pending_subchannel_updates_; grpc_closure closure_; }; @@ -946,89 +1225,6 @@ void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( &self->chand_->state_tracker_, self->state_, &self->my_closure_); } -// -// ChannelData::GrpcSubchannel -// - -// This class is a wrapper for Subchannel that hides details of the -// channel's implementation (such as the health check service name) from -// the LB policy API. -// -// Note that no synchronization is needed here, because even if the -// underlying subchannel is shared between channels, this wrapper will only -// be used within one channel, so it will always be synchronized by the -// control plane combiner. -class ChannelData::GrpcSubchannel : public SubchannelInterface { - public: - GrpcSubchannel(ChannelData* chand, Subchannel* subchannel, - UniquePtr health_check_service_name) - : chand_(chand), - subchannel_(subchannel), - health_check_service_name_(std::move(health_check_service_name)) { - GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "GrpcSubchannel"); - auto* subchannel_node = subchannel_->channelz_node(); - if (subchannel_node != nullptr) { - intptr_t subchannel_uuid = subchannel_node->uuid(); - auto it = chand_->subchannel_refcount_map_.find(subchannel_); - if (it == chand_->subchannel_refcount_map_.end()) { - chand_->channelz_node_->AddChildSubchannel(subchannel_uuid); - it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first; - } - ++it->second; - } - } - - ~GrpcSubchannel() { - auto* subchannel_node = subchannel_->channelz_node(); - if (subchannel_node != nullptr) { - intptr_t subchannel_uuid = subchannel_node->uuid(); - auto it = chand_->subchannel_refcount_map_.find(subchannel_); - GPR_ASSERT(it != chand_->subchannel_refcount_map_.end()); - --it->second; - if (it->second == 0) { - chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid); - chand_->subchannel_refcount_map_.erase(it); - } - } - GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); - GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "GrpcSubchannel"); - } - - grpc_connectivity_state CheckConnectivityState( - RefCountedPtr* connected_subchannel) - override { - RefCountedPtr tmp; - auto retval = subchannel_->CheckConnectivityState( - health_check_service_name_.get(), &tmp); - *connected_subchannel = std::move(tmp); - return retval; - } - - void WatchConnectivityState( - grpc_connectivity_state initial_state, - UniquePtr watcher) override { - subchannel_->WatchConnectivityState( - initial_state, - UniquePtr(gpr_strdup(health_check_service_name_.get())), - std::move(watcher)); - } - - void CancelConnectivityStateWatch( - ConnectivityStateWatcher* watcher) override { - subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(), - watcher); - } - - void AttemptToConnect() override { subchannel_->AttemptToConnect(); } - - void ResetBackoff() override { subchannel_->ResetBackoff(); } - - private: - ChannelData* chand_; - Subchannel* subchannel_; - UniquePtr health_check_service_name_; -}; - // // ChannelData::ClientChannelControlHelper // @@ -1066,8 +1262,8 @@ class ChannelData::ClientChannelControlHelper chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) return nullptr; - return MakeRefCounted(chand_, subchannel, - std::move(health_check_service_name)); + return MakeRefCounted( + chand_, subchannel, std::move(health_check_service_name)); } grpc_channel* CreateChannel(const char* target, @@ -1078,8 +1274,7 @@ class ChannelData::ClientChannelControlHelper void UpdateState( grpc_connectivity_state state, UniquePtr picker) override { - grpc_error* disconnect_error = - chand_->disconnect_error_.Load(MemoryOrder::ACQUIRE); + grpc_error* disconnect_error = chand_->disconnect_error(); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { const char* extra = disconnect_error == GRPC_ERROR_NONE ? "" @@ -1444,9 +1639,13 @@ grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { } LoadBalancingPolicy::PickResult result = picker_->Pick(LoadBalancingPolicy::PickArgs()); - if (result.connected_subchannel != nullptr) { - ConnectedSubchannel* connected_subchannel = - static_cast(result.connected_subchannel.get()); + ConnectedSubchannel* connected_subchannel = nullptr; + if (result.subchannel != nullptr) { + SubchannelWrapper* subchannel = + static_cast(result.subchannel.get()); + connected_subchannel = subchannel->connected_subchannel(); + } + if (connected_subchannel != nullptr) { connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); } else { if (result.error == GRPC_ERROR_NONE) { @@ -1489,6 +1688,10 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { } // Disconnect. if (op->disconnect_with_error != GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { + gpr_log(GPR_INFO, "chand=%p: channel shut down from API: %s", chand, + grpc_error_string(op->disconnect_with_error)); + } grpc_error* error = GRPC_ERROR_NONE; GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( &error, op->disconnect_with_error, MemoryOrder::ACQ_REL, @@ -1563,6 +1766,17 @@ void ChannelData::RemoveQueuedPick(QueuedPick* to_remove, } } +RefCountedPtr +ChannelData::GetConnectedSubchannelInDataPlane( + SubchannelInterface* subchannel) const { + SubchannelWrapper* subchannel_wrapper = + static_cast(subchannel); + ConnectedSubchannel* connected_subchannel = + subchannel_wrapper->connected_subchannel_in_data_plane(); + if (connected_subchannel == nullptr) return nullptr; + return connected_subchannel->Ref(); +} + void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { auto* chand = static_cast(arg); if (chand->resolving_lb_policy_ != nullptr) { @@ -3490,10 +3704,9 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { auto result = chand->picker()->Pick(pick_args); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, - "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " - "error=%s)", + "chand=%p calld=%p: LB pick returned %s (subchannel=%p, error=%s)", chand, calld, PickResultTypeName(result.type), - result.connected_subchannel.get(), grpc_error_string(result.error)); + result.subchannel.get(), grpc_error_string(result.error)); } switch (result.type) { case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: { @@ -3535,11 +3748,16 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { break; default: // PICK_COMPLETE // Handle drops. - if (GPR_UNLIKELY(result.connected_subchannel == nullptr)) { + if (GPR_UNLIKELY(result.subchannel == nullptr)) { result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Call dropped by load balancing policy"); + } else { + // Grab a ref to the connected subchannel while we're still + // holding the data plane combiner. + calld->connected_subchannel_ = + chand->GetConnectedSubchannelInDataPlane(result.subchannel.get()); + GPR_ASSERT(calld->connected_subchannel_ != nullptr); } - calld->connected_subchannel_ = std::move(result.connected_subchannel); calld->lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready; calld->lb_recv_trailing_metadata_ready_user_data_ = diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index d508932015d..ccaeffe269c 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -128,7 +128,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Used only if type is PICK_COMPLETE. Will be set to the selected /// subchannel, or nullptr if the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; + RefCountedPtr subchannel; /// Used only if type is PICK_TRANSIENT_FAILURE. /// Error to be set when returning a transient failure. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a87dfda7321..dad10f0ce86 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -575,13 +575,12 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) { result = child_picker_->Pick(args); // If pick succeeded, add LB token to initial metadata. if (result.type == PickResult::PICK_COMPLETE && - result.connected_subchannel != nullptr) { + result.subchannel != nullptr) { const grpc_arg* arg = grpc_channel_args_find( - result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + result.subchannel->channel_args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); if (arg == nullptr) { - gpr_log(GPR_ERROR, - "[grpclb %p picker %p] No LB token for connected subchannel %p", - parent_, this, result.connected_subchannel.get()); + gpr_log(GPR_ERROR, "[grpclb %p picker %p] No LB token for subchannel %p", + parent_, this, result.subchannel.get()); abort(); } grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index e4b58eb7558..de17b1f046e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/sync.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -85,9 +84,8 @@ class PickFirst : public LoadBalancingPolicy { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, - grpc_combiner* combiner, const grpc_channel_args& args) - : SubchannelList(policy, tracer, addresses, combiner, + : SubchannelList(policy, tracer, addresses, policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' @@ -111,19 +109,18 @@ class PickFirst : public LoadBalancingPolicy { class Picker : public SubchannelPicker { public: - explicit Picker( - RefCountedPtr connected_subchannel) - : connected_subchannel_(std::move(connected_subchannel)) {} + explicit Picker(RefCountedPtr subchannel) + : subchannel_(std::move(subchannel)) {} PickResult Pick(PickArgs args) override { PickResult result; result.type = PickResult::PICK_COMPLETE; - result.connected_subchannel = connected_subchannel_; + result.subchannel = subchannel_; return result; } private: - RefCountedPtr connected_subchannel_; + RefCountedPtr subchannel_; }; void ShutdownLocked() override; @@ -166,6 +163,9 @@ void PickFirst::ShutdownLocked() { void PickFirst::ExitIdleLocked() { if (shutdown_) return; if (idle_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, "Pick First %p exiting idle", this); + } idle_ = false; if (subchannel_list_ == nullptr || subchannel_list_->num_subchannels() == 0) { @@ -200,7 +200,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current @@ -350,8 +350,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // some connectivity state notifications. if (connectivity_state == GRPC_CHANNEL_READY) { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, UniquePtr(New( - connected_subchannel()->Ref()))); + GRPC_CHANNEL_READY, + UniquePtr(New(subchannel()->Ref()))); } else { // CONNECTING p->channel_control_helper()->UpdateState( connectivity_state, @@ -445,13 +445,13 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } // Cases 1 and 2. - p->selected_ = this; - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, - UniquePtr(New(connected_subchannel()->Ref()))); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } + p->selected_ = this; + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, + UniquePtr(New(subchannel()->Ref()))); } void PickFirst::PickFirstSubchannelData:: diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 17c65d8b551..02bd319e37e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -38,7 +38,6 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/sync.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/static_metadata.h" @@ -106,9 +105,8 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, - grpc_combiner* combiner, const grpc_channel_args& args) - : SubchannelList(policy, tracer, addresses, combiner, + : SubchannelList(policy, tracer, addresses, policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' @@ -155,7 +153,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobin* parent_; size_t last_picked_index_; - InlinedVector, 10> subchannels_; + InlinedVector, 10> subchannels_; }; void ShutdownLocked() override; @@ -180,10 +178,9 @@ RoundRobin::Picker::Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list) : parent_(parent) { for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { - auto* connected_subchannel = - subchannel_list->subchannel(i)->connected_subchannel(); - if (connected_subchannel != nullptr) { - subchannels_.push_back(connected_subchannel->Ref()); + RoundRobinSubchannelData* sd = subchannel_list->subchannel(i); + if (sd->connectivity_state() == GRPC_CHANNEL_READY) { + subchannels_.push_back(sd->subchannel()->Ref()); } } // For discussion on why we generate a random starting index for @@ -204,14 +201,13 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs args) { last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, - "[RR %p picker %p] returning index %" PRIuPTR - ", connected_subchannel=%p", + "[RR %p picker %p] returning index %" PRIuPTR ", subchannel=%p", parent_, this, last_picked_index_, subchannels_[last_picked_index_].get()); } PickResult result; result.type = PickResult::PICK_COMPLETE; - result.connected_subchannel = subchannels_[last_picked_index_]; + result.subchannel = subchannels_[last_picked_index_]; return result; } @@ -424,7 +420,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); + this, &grpc_lb_round_robin_trace, args.addresses, *args.args); if (latest_pending_subchannel_list_->num_subchannels() == 0) { // If the new list is empty, immediately promote the new list to the // current list and transition to TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 7d70928a83c..34cd0f549fe 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -39,7 +39,6 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -64,8 +63,7 @@ class MySubchannelList }; */ -// All methods with a Locked() suffix must be called from within the -// client_channel combiner. +// All methods will be called from within the client_channel combiner. namespace grpc_core { @@ -93,20 +91,13 @@ class SubchannelData { // Returns a pointer to the subchannel. SubchannelInterface* subchannel() const { return subchannel_.get(); } - // Returns the connected subchannel. Will be null if the subchannel - // is not connected. - ConnectedSubchannelInterface* connected_subchannel() const { - return connected_subchannel_.get(); - } - // Synchronously checks the subchannel's connectivity state. // Must not be called while there is a connectivity notification // pending (i.e., between calling StartConnectivityWatchLocked() and // calling CancelConnectivityWatchLocked()). grpc_connectivity_state CheckConnectivityStateLocked() { GPR_ASSERT(pending_watcher_ == nullptr); - connectivity_state_ = - subchannel()->CheckConnectivityState(&connected_subchannel_); + connectivity_state_ = subchannel_->CheckConnectivityState(); return connectivity_state_; } @@ -144,7 +135,8 @@ class SubchannelData { private: // Watcher for subchannel connectivity state. - class Watcher : public SubchannelInterface::ConnectivityStateWatcher { + class Watcher + : public SubchannelInterface::ConnectivityStateWatcherInterface { public: Watcher( SubchannelData* subchannel_data, @@ -154,42 +146,13 @@ class SubchannelData { ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } - void OnConnectivityStateChange(grpc_connectivity_state new_state, - RefCountedPtr - connected_subchannel) override; + void OnConnectivityStateChange(grpc_connectivity_state new_state) override; grpc_pollset_set* interested_parties() override { return subchannel_list_->policy()->interested_parties(); } private: - // A fire-and-forget class that bounces into the combiner to process - // a connectivity state update. - class Updater { - public: - Updater( - SubchannelData* - subchannel_data, - RefCountedPtr> - subchannel_list, - grpc_connectivity_state state, - RefCountedPtr connected_subchannel); - - ~Updater() { - subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor"); - } - - private: - static void OnUpdateLocked(void* arg, grpc_error* error); - - SubchannelData* subchannel_data_; - RefCountedPtr> - subchannel_list_; - const grpc_connectivity_state state_; - RefCountedPtr connected_subchannel_; - grpc_closure closure_; - }; - SubchannelData* subchannel_data_; RefCountedPtr subchannel_list_; }; @@ -202,10 +165,10 @@ class SubchannelData { // The subchannel. RefCountedPtr subchannel_; // Will be non-null when the subchannel's state is being watched. - SubchannelInterface::ConnectivityStateWatcher* pending_watcher_ = nullptr; + SubchannelInterface::ConnectivityStateWatcherInterface* pending_watcher_ = + nullptr; // Data updated by the watcher. grpc_connectivity_state connectivity_state_; - RefCountedPtr connected_subchannel_; }; // A list of subchannels. @@ -232,7 +195,6 @@ class SubchannelList : public InternallyRefCounted { // the backoff code out of subchannels and into LB policies. void ResetBackoffLocked(); - // Note: Caller must ensure that this is invoked inside of the combiner. void Orphan() override { ShutdownLocked(); InternallyRefCounted::Unref(DEBUG_LOCATION, "shutdown"); @@ -242,7 +204,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args); @@ -263,8 +225,6 @@ class SubchannelList : public InternallyRefCounted { TraceFlag* tracer_; - grpc_combiner* combiner_; - // The list of subchannels. SubchannelVector subchannels_; @@ -284,59 +244,26 @@ class SubchannelList : public InternallyRefCounted { template void SubchannelData::Watcher:: - OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) { - // Will delete itself. - New(subchannel_data_, - subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"), - new_state, std::move(connected_subchannel)); -} - -template -SubchannelData::Watcher::Updater:: - Updater( - SubchannelData* subchannel_data, - RefCountedPtr> - subchannel_list, - grpc_connectivity_state state, - RefCountedPtr connected_subchannel) - : subchannel_data_(subchannel_data), - subchannel_list_(std::move(subchannel_list)), - state_(state), - connected_subchannel_(std::move(connected_subchannel)) { - GRPC_CLOSURE_INIT(&closure_, &OnUpdateLocked, this, - grpc_combiner_scheduler(subchannel_list_->combiner_)); - GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); -} - -template -void SubchannelData::Watcher::Updater:: - OnUpdateLocked(void* arg, grpc_error* error) { - Updater* self = static_cast(arg); - SubchannelData* sd = self->subchannel_data_; - if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) { + OnConnectivityStateChange(grpc_connectivity_state new_state) { + if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR " (subchannel %p): connectivity changed: state=%s, " - "connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", - sd->subchannel_list_->tracer()->name(), - sd->subchannel_list_->policy(), sd->subchannel_list_, sd->Index(), - sd->subchannel_list_->num_subchannels(), sd->subchannel_.get(), - grpc_connectivity_state_name(self->state_), - self->connected_subchannel_.get(), - sd->subchannel_list_->shutting_down(), sd->pending_watcher_); + "shutting_down=%d, pending_watcher=%p", + subchannel_list_->tracer()->name(), subchannel_list_->policy(), + subchannel_list_.get(), subchannel_data_->Index(), + subchannel_list_->num_subchannels(), + subchannel_data_->subchannel_.get(), + grpc_connectivity_state_name(new_state), + subchannel_list_->shutting_down(), + subchannel_data_->pending_watcher_); } - if (!sd->subchannel_list_->shutting_down() && - sd->pending_watcher_ != nullptr) { - sd->connectivity_state_ = self->state_; - // Get or release ref to connected subchannel. - sd->connected_subchannel_ = std::move(self->connected_subchannel_); + if (!subchannel_list_->shutting_down() && + subchannel_data_->pending_watcher_ != nullptr) { + subchannel_data_->connectivity_state_ = new_state; // Call the subclass's ProcessConnectivityChangeLocked() method. - sd->ProcessConnectivityChangeLocked(sd->connectivity_state_); + subchannel_data_->ProcessConnectivityChangeLocked(new_state); } - // Clean up. - Delete(self); } // @@ -371,7 +298,6 @@ void SubchannelData:: subchannel_.get()); } subchannel_.reset(); - connected_subchannel_.reset(); } } @@ -400,7 +326,7 @@ void SubchannelData(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); subchannel_->WatchConnectivityState( connectivity_state_, - UniquePtr( + UniquePtr( pending_watcher_)); } @@ -434,13 +360,12 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, + const ServerAddressList& addresses, LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), - tracer_(tracer), - combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) { + tracer_(tracer) { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", @@ -509,7 +434,6 @@ SubchannelList::~SubchannelList() { gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(), policy_, this); } - GRPC_COMBINER_UNREF(combiner_, "subchannel_list"); } template diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 136d85bba14..ad030c17b5e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -554,7 +554,7 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs args) { PickResult result = PickFromLocality(key, args); // If pick succeeded, add client stats. if (result.type == PickResult::PICK_COMPLETE && - result.connected_subchannel != nullptr && client_stats_ != nullptr) { + result.subchannel != nullptr && client_stats_ != nullptr) { // TODO(roth): Add support for client stats. } return result; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index dd16eded826..99c7721e5e5 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -86,7 +86,7 @@ ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, RefCountedPtr channelz_subchannel, intptr_t socket_uuid) - : ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount), + : RefCounted(&grpc_trace_subchannel_refcount), channel_stack_(channel_stack), args_(grpc_channel_args_copy(args)), channelz_subchannel_(std::move(channelz_subchannel)), @@ -378,12 +378,12 @@ class Subchannel::ConnectedSubchannelStateWatcher { // void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( - UniquePtr watcher) { + OrphanablePtr watcher) { watchers_.insert(MakePair(watcher.get(), std::move(watcher))); } void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( - ConnectivityStateWatcher* watcher) { + ConnectivityStateWatcherInterface* watcher) { watchers_.erase(watcher); } @@ -438,8 +438,9 @@ class Subchannel::HealthWatcherMap::HealthWatcher grpc_connectivity_state state() const { return state_; } - void AddWatcherLocked(grpc_connectivity_state initial_state, - UniquePtr watcher) { + void AddWatcherLocked( + grpc_connectivity_state initial_state, + OrphanablePtr watcher) { if (state_ != initial_state) { RefCountedPtr connected_subchannel; if (state_ == GRPC_CHANNEL_READY) { @@ -451,7 +452,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher watcher_list_.AddWatcherLocked(std::move(watcher)); } - void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) { + void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher) { watcher_list_.RemoveWatcherLocked(watcher); } @@ -527,7 +528,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher void Subchannel::HealthWatcherMap::AddWatcherLocked( Subchannel* subchannel, grpc_connectivity_state initial_state, UniquePtr health_check_service_name, - UniquePtr watcher) { + OrphanablePtr watcher) { // If the health check service name is not already present in the map, // add it. auto it = map_.find(health_check_service_name.get()); @@ -546,7 +547,8 @@ void Subchannel::HealthWatcherMap::AddWatcherLocked( } void Subchannel::HealthWatcherMap::RemoveWatcherLocked( - const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + const char* health_check_service_name, + ConnectivityStateWatcherInterface* watcher) { auto it = map_.find(health_check_service_name); GPR_ASSERT(it != map_.end()); it->second->RemoveWatcherLocked(watcher); @@ -818,7 +820,7 @@ grpc_connectivity_state Subchannel::CheckConnectivityState( void Subchannel::WatchConnectivityState( grpc_connectivity_state initial_state, UniquePtr health_check_service_name, - UniquePtr watcher) { + OrphanablePtr watcher) { MutexLock lock(&mu_); grpc_pollset_set* interested_parties = watcher->interested_parties(); if (interested_parties != nullptr) { @@ -837,7 +839,8 @@ void Subchannel::WatchConnectivityState( } void Subchannel::CancelConnectivityStateWatch( - const char* health_check_service_name, ConnectivityStateWatcher* watcher) { + const char* health_check_service_name, + ConnectivityStateWatcherInterface* watcher) { MutexLock lock(&mu_); grpc_pollset_set* interested_parties = watcher->interested_parties(); if (interested_parties != nullptr) { diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 2f05792b872..9e8de767839 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,7 +23,6 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" -#include "src/core/ext/filters/client_channel/subchannel_interface.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" @@ -70,7 +69,7 @@ namespace grpc_core { class SubchannelCall; -class ConnectedSubchannel : public ConnectedSubchannelInterface { +class ConnectedSubchannel : public RefCounted { public: struct CallArgs { grpc_polling_entity* pollent; @@ -97,7 +96,7 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } - const grpc_channel_args* args() const override { return args_; } + const grpc_channel_args* args() const { return args_; } channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } @@ -176,10 +175,35 @@ class SubchannelCall { // A subchannel that knows how to connect to exactly one target address. It // provides a target for load balancing. +// +// Note that this is the "real" subchannel implementation, whose API is +// different from the SubchannelInterface that is exposed to LB policy +// implementations. The client channel provides an adaptor class +// (SubchannelWrapper) that "converts" between the two. class Subchannel { public: - typedef SubchannelInterface::ConnectivityStateWatcher - ConnectivityStateWatcher; + class ConnectivityStateWatcherInterface + : public InternallyRefCounted { + public: + virtual ~ConnectivityStateWatcherInterface() = default; + + // Will be invoked whenever the subchannel's connectivity state + // changes. There will be only one invocation of this method on a + // given watcher instance at any given time. + // + // When the state changes to READY, connected_subchannel will + // contain a ref to the connected subchannel. When it changes from + // READY to some other state, the implementation must release its + // ref to the connected subchannel. + virtual void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) // NOLINT + GRPC_ABSTRACT; + + virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, @@ -206,6 +230,8 @@ class Subchannel { // Caller doesn't take ownership. const char* GetTargetAddress(); + const grpc_channel_args* channel_args() const { return args_; } + channelz::SubchannelNode* channelz_node(); // Returns the current connectivity state of the subchannel. @@ -225,14 +251,15 @@ class Subchannel { // changes. // The watcher will be destroyed either when the subchannel is // destroyed or when CancelConnectivityStateWatch() is called. - void WatchConnectivityState(grpc_connectivity_state initial_state, - UniquePtr health_check_service_name, - UniquePtr watcher); + void WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + OrphanablePtr watcher); // Cancels a connectivity state watch. // If the watcher has already been destroyed, this is a no-op. void CancelConnectivityStateWatch(const char* health_check_service_name, - ConnectivityStateWatcher* watcher); + ConnectivityStateWatcherInterface* watcher); // Attempt to connect to the backend. Has no effect if already connected. void AttemptToConnect(); @@ -257,14 +284,15 @@ class Subchannel { grpc_resolved_address* addr); private: - // A linked list of ConnectivityStateWatchers that are monitoring the - // subchannel's state. + // A linked list of ConnectivityStateWatcherInterfaces that are monitoring + // the subchannel's state. class ConnectivityStateWatcherList { public: ~ConnectivityStateWatcherList() { Clear(); } - void AddWatcherLocked(UniquePtr watcher); - void RemoveWatcherLocked(ConnectivityStateWatcher* watcher); + void AddWatcherLocked( + OrphanablePtr watcher); + void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher); // Notifies all watchers in the list about a change to state. void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); @@ -276,12 +304,13 @@ class Subchannel { private: // TODO(roth): This could be a set instead of a map if we had a set // implementation. - Map> + Map> watchers_; }; - // A map that tracks ConnectivityStateWatchers using a particular health - // check service name. + // A map that tracks ConnectivityStateWatcherInterfaces using a particular + // health check service name. // // There is one entry in the map for each health check service name. // Entries exist only as long as there are watchers using the @@ -291,12 +320,12 @@ class Subchannel { // state READY. class HealthWatcherMap { public: - void AddWatcherLocked(Subchannel* subchannel, - grpc_connectivity_state initial_state, - UniquePtr health_check_service_name, - UniquePtr watcher); + void AddWatcherLocked( + Subchannel* subchannel, grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + OrphanablePtr watcher); void RemoveWatcherLocked(const char* health_check_service_name, - ConnectivityStateWatcher* watcher); + ConnectivityStateWatcherInterface* watcher); // Notifies the watcher when the subchannel's state changes. void NotifyLocked(grpc_connectivity_state state); diff --git a/src/core/ext/filters/client_channel/subchannel_interface.h b/src/core/ext/filters/client_channel/subchannel_interface.h index 10b1bf124c2..2e448dc5a64 100644 --- a/src/core/ext/filters/client_channel/subchannel_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_interface.h @@ -21,42 +21,22 @@ #include -#include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { -// TODO(roth): In a subsequent PR, remove this from this API. -class ConnectedSubchannelInterface - : public RefCounted { - public: - virtual const grpc_channel_args* args() const GRPC_ABSTRACT; - - protected: - template - explicit ConnectedSubchannelInterface(TraceFlagT* trace_flag = nullptr) - : RefCounted(trace_flag) {} -}; - +// The interface for subchannels that is exposed to LB policy implementations. class SubchannelInterface : public RefCounted { public: - class ConnectivityStateWatcher { + class ConnectivityStateWatcherInterface { public: - virtual ~ConnectivityStateWatcher() = default; + virtual ~ConnectivityStateWatcherInterface() = default; // Will be invoked whenever the subchannel's connectivity state // changes. There will be only one invocation of this method on a // given watcher instance at any given time. - // - // When the state changes to READY, connected_subchannel will - // contain a ref to the connected subchannel. When it changes from - // READY to some other state, the implementation must release its - // ref to the connected subchannel. - virtual void OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr - connected_subchannel) // NOLINT + virtual void OnConnectivityStateChange(grpc_connectivity_state new_state) GRPC_ABSTRACT; // TODO(roth): Remove this as soon as we move to EventManager-based @@ -66,12 +46,14 @@ class SubchannelInterface : public RefCounted { GRPC_ABSTRACT_BASE_CLASS }; + template + explicit SubchannelInterface(TraceFlagT* trace_flag = nullptr) + : RefCounted(trace_flag) {} + virtual ~SubchannelInterface() = default; // Returns the current connectivity state of the subchannel. - virtual grpc_connectivity_state CheckConnectivityState( - RefCountedPtr* connected_subchannel) - GRPC_ABSTRACT; + virtual grpc_connectivity_state CheckConnectivityState() GRPC_ABSTRACT; // Starts watching the subchannel's connectivity state. // The first callback to the watcher will be delivered when the @@ -86,12 +68,12 @@ class SubchannelInterface : public RefCounted { // the previous watcher using CancelConnectivityStateWatch(). virtual void WatchConnectivityState( grpc_connectivity_state initial_state, - UniquePtr watcher) GRPC_ABSTRACT; + UniquePtr watcher) GRPC_ABSTRACT; // Cancels a connectivity state watch. // If the watcher has already been destroyed, this is a no-op. - virtual void CancelConnectivityStateWatch(ConnectivityStateWatcher* watcher) - GRPC_ABSTRACT; + virtual void CancelConnectivityStateWatch( + ConnectivityStateWatcherInterface* watcher) GRPC_ABSTRACT; // Attempt to connect to the backend. Has no effect if already connected. // If the subchannel is currently in backoff delay due to a previously @@ -105,6 +87,9 @@ class SubchannelInterface : public RefCounted { // attempt will be started as soon as AttemptToConnect() is called. virtual void ResetBackoff() GRPC_ABSTRACT; + // TODO(roth): Need a better non-grpc-specific abstraction here. + virtual const grpc_channel_args* channel_args() GRPC_ABSTRACT; + GRPC_ABSTRACT_BASE_CLASS }; diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h index 36e32d60c07..566691df580 100644 --- a/src/core/lib/gprpp/map.h +++ b/src/core/lib/gprpp/map.h @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/pair.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { struct StringLess { @@ -41,6 +42,13 @@ struct StringLess { } }; +template +struct RefCountedPtrLess { + bool operator()(const RefCountedPtr& p1, const RefCountedPtr& p2) { + return p1.get() < p2.get(); + } +}; + namespace testing { class MapTest; } @@ -55,8 +63,28 @@ class Map { typedef Compare key_compare; class iterator; + Map() {} ~Map() { clear(); } + // Copying not currently supported. + Map(const Map& other) = delete; + + // Move support. + Map(Map&& other) : root_(other.root_), size_(other.size_) { + other.root_ = nullptr; + other.size_ = 0; + } + Map& operator=(Map&& other) { + if (this != &other) { + clear(); + root_ = other.root_; + size_ = other.size_; + other.root_ = nullptr; + other.size_ = 0; + } + return *this; + } + T& operator[](key_type&& key); T& operator[](const key_type& key); iterator find(const key_type& k); diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 1523ced16d8..7766ee186c6 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -222,7 +222,12 @@ void grpc_mdctx_global_shutdown() { abort(); } } + // For ASAN builds, we don't want to crash here, because that will + // prevent ASAN from providing leak detection information, which is + // far more useful than this simple assertion. +#ifndef GRPC_ASAN_ENABLED GPR_DEBUG_ASSERT(shard->count == 0); +#endif gpr_free(shard->elems); } } diff --git a/test/core/gprpp/map_test.cc b/test/core/gprpp/map_test.cc index 30d9eb0b207..21aeee82486 100644 --- a/test/core/gprpp/map_test.cc +++ b/test/core/gprpp/map_test.cc @@ -437,6 +437,35 @@ TEST_F(MapTest, LowerBound) { EXPECT_EQ(it, test_map.end()); } +// Test move ctor +TEST_F(MapTest, MoveCtor) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + Map test_map2 = std::move(test_map); + for (int i = 0; i < 5; i++) { + EXPECT_EQ(test_map.end(), test_map.find(kKeys[i])); + EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data()); + } +} + +// Test move assignment +TEST_F(MapTest, MoveAssignment) { + Map test_map; + for (int i = 0; i < 5; i++) { + test_map.emplace(kKeys[i], Payload(i)); + } + Map test_map2; + test_map2.emplace("xxx", Payload(123)); + test_map2 = std::move(test_map); + for (int i = 0; i < 5; i++) { + EXPECT_EQ(test_map.end(), test_map.find(kKeys[i])); + EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data()); + } + EXPECT_EQ(test_map2.end(), test_map2.find("xxx")); +} + } // namespace testing } // namespace grpc_core diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 2c1f988d173..041ce1f45a1 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -117,7 +117,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy PickResult Pick(PickArgs args) override { PickResult result = delegate_picker_->Pick(args); if (result.type == PickResult::PICK_COMPLETE && - result.connected_subchannel != nullptr) { + result.subchannel != nullptr) { new (args.call_state->Alloc(sizeof(TrailingMetadataHandler))) TrailingMetadataHandler(&result, cb_, user_data_); } From 93c8088b332c02e505743e3ad06ecbd31ccb863a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Jun 2019 12:10:08 -0700 Subject: [PATCH 311/676] Implement global interceptor --- .../GRPCClient/GRPCCall+Interceptor.h | 29 ++++ .../GRPCClient/GRPCCall+Interceptor.m | 60 +++++++ src/objective-c/GRPCClient/GRPCCall.m | 37 +++- .../tests/InteropTests/InteropTests.m | 158 +++++++++++++++++- 4 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 src/objective-c/GRPCClient/GRPCCall+Interceptor.h create mode 100644 src/objective-c/GRPCClient/GRPCCall+Interceptor.m diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.h b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h new file mode 100644 index 00000000000..953846d8c99 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h @@ -0,0 +1,29 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "GRPCCall.h" + +@protocol GRPCInterceptorFactory; + +@interface GRPCCall2 (Interceptor) + ++ (void)registerGlobalInterceptor:(id)interceptorFactory; + ++ (id)globalInterceptorFactory; + +@end diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.m b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m new file mode 100644 index 00000000000..b1cad75d4f3 --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m @@ -0,0 +1,60 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "GRPCCall+Interceptor.h" +#import "GRPCInterceptor.h" + +static id globalInterceptorFactory = nil; +static NSLock *globalInterceptorLock = nil; +static dispatch_once_t onceToken; + +@implementation GRPCCall2 (Interceptor) + ++ (void)registerGlobalInterceptor:(id)interceptorFactory { + dispatch_once(&onceToken, ^{ + globalInterceptorLock = [[NSLock alloc] init]; + }); + [globalInterceptorLock lock]; + NSAssert(globalInterceptorFactory == nil, + @"Global interceptor is already registered. Only one global interceptor can be " + @"registered in a process"); + if (globalInterceptorFactory != nil) { + NSLog( + @"Global interceptor is already registered. Only one global interceptor can be registered " + @"in a process"); + [globalInterceptorLock unlock]; + return; + } + + globalInterceptorFactory = interceptorFactory; + [globalInterceptorLock unlock]; +} + ++ (id)globalInterceptorFactory { + dispatch_once(&onceToken, ^{ + globalInterceptorLock = [[NSLock alloc] init]; + }); + id factory; + [globalInterceptorLock lock]; + factory = globalInterceptorFactory; + [globalInterceptorLock unlock]; + + return factory; +} + +@end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e97ed6e3a9e..684867ae1ee 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -17,6 +17,7 @@ */ #import "GRPCCall.h" +#import "GRPCCall+Interceptor.h" #import "GRPCCall+OAuth2.h" #import "GRPCCallOptions.h" #import "GRPCInterceptor.h" @@ -141,23 +142,51 @@ const char *kCFStreamVarName = "grpc_cfstream"; _responseHandler = responseHandler; // Initialize the interceptor chain + + // First initialize the internal call GRPCCall2Internal *internalCall = [[GRPCCall2Internal alloc] init]; id nextInterceptor = internalCall; GRPCInterceptorManager *nextManager = nil; + + // Then initialize the global interceptor, if applicable + id globalInterceptorFactory = [GRPCCall2 globalInterceptorFactory]; + if (globalInterceptorFactory) { + GRPCInterceptorManager *manager = + [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; + GRPCInterceptor *interceptor = + [globalInterceptorFactory createInterceptorWithManager:manager]; + NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", + globalInterceptorFactory); + if (interceptor == nil) { + NSLog(@"Failed to create interceptor from factory: %@", globalInterceptorFactory); + } else { + [internalCall setResponseHandler:interceptor]; + } + nextInterceptor = interceptor; + nextManager = manager; + } + + // Finanlly initialize the interceptors in the chain NSArray *interceptorFactories = _actualCallOptions.interceptorFactories; if (interceptorFactories.count == 0) { - [internalCall setResponseHandler:_responseHandler]; + if (nextManager == nil) { + [internalCall setResponseHandler:_responseHandler]; + } else { + [nextManager setPreviousInterceptor:_responseHandler]; + } } else { for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { GRPCInterceptorManager *manager = [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; GRPCInterceptor *interceptor = [interceptorFactories[i] createInterceptorWithManager:manager]; - NSAssert(interceptor != nil, @"Failed to create interceptor"); + NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", + interceptorFactories[i]); if (interceptor == nil) { - return nil; + NSLog(@"Failed to create interceptor from factory: %@", interceptorFactories[i]); + continue; } - if (i == (int)interceptorFactories.count - 1) { + if (nextManager == nil) { [internalCall setResponseHandler:interceptor]; } else { [nextManager setPreviousInterceptor:interceptor]; diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 91e133a1300..ef22a53cd96 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -25,6 +25,7 @@ #endif #import #import +#import #import #import #import @@ -1224,7 +1225,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - (void)testDefaultInterceptor { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"testDefaultInterceptor"]; NSArray *requests = @[ @27182, @8, @1828, @45904 ]; NSArray *responses = @[ @31415, @9, @2653, @58979 ]; @@ -1277,7 +1279,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - (void)testLoggingInterceptor { XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"testLoggingInterceptor"]; __block NSUInteger startCount = 0; __block NSUInteger writeDataCount = 0; @@ -1400,7 +1403,8 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - (void)testHijackingInterceptor { NSUInteger kCancelAfterWrites = 2; XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"PingPongWithV2API"]; + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"testHijackingInterceptor"]; NSArray *responses = @[ @1, @2, @3, @4 ]; __block int index = 0; @@ -1514,4 +1518,152 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager XCTAssertEqual(responseCloseCount, 1); } +- (void)testGlobalInterceptor { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"testLoggingInterceptor"]; + + __block NSUInteger startCount = 0; + __block NSUInteger writeDataCount = 0; + __block NSUInteger finishCount = 0; + __block NSUInteger receiveNextMessageCount = 0; + __block NSUInteger responseHeaderCount = 0; + __block NSUInteger responseDataCount = 0; + __block NSUInteger responseCloseCount = 0; + __block NSUInteger didWriteDataCount = 0; + id factory = [[HookInterceptorFactory alloc] + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + startCount++; + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] + callOptions:[callOptions copy]]; + } + writeDataHook:^(id data, GRPCInterceptorManager *manager) { + writeDataCount++; + [manager writeNextInterceptorWithData:data]; + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + [manager finishNextInterceptor]; + } + receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { + receiveNextMessageCount++; + [manager receiveNextInterceptorMessages:numberOfMessages]; + } + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(id data, GRPCInterceptorManager *manager) { + responseDataCount++; + [manager forwardPreviousInterceptorWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager) { + responseCloseCount++; + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; + } + didWriteDataHook:^(GRPCInterceptorManager *manager) { + didWriteDataCount++; + [manager forwardPreviousInterceptorDidWriteData]; + }]; + + NSArray *requests = @[ @1, @2, @3, @4 ]; + NSArray *responses = @[ @1, @2, @3, @4 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.flowControlEnabled = YES; + [GRPCCall2 registerGlobalInterceptor:factory]; + + __block BOOL canWriteData = NO; + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + XCTAssertLessThan(index, 4, + @"More than 4 responses received."); + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + XCTAssertTrue(canWriteData); + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + XCTAssertNil(error, + @"Finished with unexpected error: %@", + error); + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + XCTAssertEqual(startCount, 1); + XCTAssertEqual(writeDataCount, 4); + XCTAssertEqual(finishCount, 1); + XCTAssertEqual(receiveNextMessageCount, 4); + XCTAssertEqual(responseHeaderCount, 1); + XCTAssertEqual(responseDataCount, 4); + XCTAssertEqual(responseCloseCount, 1); + XCTAssertEqual(didWriteDataCount, 4); +} + +- (void)testConflictingGlobalInterceptors { + id factory = [[HookInterceptorFactory alloc] + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:nil + writeDataHook:nil + finishHook:nil + receiveNextMessagesHook:nil + responseHeaderHook:nil + responseDataHook:nil + responseCloseHook:nil + didWriteDataHook:nil]; + id factory2 = [[HookInterceptorFactory alloc] + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:nil + writeDataHook:nil + finishHook:nil + receiveNextMessagesHook:nil + responseHeaderHook:nil + responseDataHook:nil + responseCloseHook:nil + didWriteDataHook:nil]; + + [GRPCCall2 registerGlobalInterceptor:factory]; + @try { + [GRPCCall2 registerGlobalInterceptor:factory2]; + XCTFail(@"Did not receive an exception when registering global interceptor the second time"); + } @catch (NSException *exception) { + NSLog(@"Received exception as expected: %@", exception); + } +} + @end From ad0b0287dfcc137da23b9896b3a8810921d9fc8e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Jun 2019 10:46:51 -0700 Subject: [PATCH 312/676] Resolve build issue --- src/core/lib/iomgr/cfstream_handle.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4f4d15966e4..05f45ed6251 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -29,6 +29,7 @@ #ifdef GRPC_CFSTREAM #import +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/lockfree_event.h" @@ -65,6 +66,9 @@ class CFStreamHandle final { dispatch_queue_t dispatch_queue_; gpr_refcount refcount_; + + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE }; #ifdef DEBUG From 21020d85c2800902f397edcfa103b18190c03546 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 12 Jun 2019 14:42:07 -0400 Subject: [PATCH 313/676] Update the doc for the new debug-only flags. --- doc/environment_variables.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 778560d4273..89ccaf825d2 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -39,7 +39,6 @@ some configuration as environment variables that can be set. gRPC C core is processing requests via debug logs. Available tracers include: - api - traces api calls to the C core - bdp_estimator - traces behavior of bdp estimation logic - - call_combiner - traces call combiner state - call_error - traces the possible errors contributing to final call status - cares_resolver - traces operations of the c-ares based DNS resolver - cares_address_sorting - traces operations of the c-ares based DNS @@ -52,9 +51,6 @@ some configuration as environment variables that can be set. - connectivity_state - traces connectivity state changes to channels - cronet - traces state in the cronet transport engine - executor - traces grpc's internal thread pool ('the executor') - - fd_trace - traces fd create(), shutdown() and close() calls for channel fds. - Also traces epoll fd create()/close() calls in epollex polling engine - traces epoll-fd creation/close calls for epollex polling engine - glb - traces the grpclb load balancer - handshaker - traces handshaking state - health_check_client - traces health checking client code @@ -85,7 +81,11 @@ some configuration as environment variables that can be set. - alarm_refcount - refcounting traces for grpc_alarm structure - metadata - tracks creation and mutation of metadata - combiner - traces combiner lock state + - call_combiner - traces call combiner state - closure - tracks closure creation, scheduling, and completion + - fd_trace - traces fd create(), shutdown() and close() calls for channel fds. + Also traces epoll fd create()/close() calls in epollex polling engine + traces epoll-fd creation/close calls for epollex polling engine - pending_tags - traces still-in-progress tags on completion queues - polling - traces the selected polling engine - polling_api - traces the api calls to polling engine From f5551f11386f149581aa9898fc9ec3ce2dc1f1fe Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 12 Jun 2019 13:49:17 -0700 Subject: [PATCH 314/676] Revert " Added some Objective C tests and minor bug fixes." --- .../GRPCClient/GRPCCall+ChannelArg.m | 3 - src/objective-c/GRPCClient/GRPCCallOptions.h | 5 +- src/objective-c/GRPCClient/GRPCCallOptions.m | 10 +- .../GRPCClient/private/GRPCChannel.m | 2 - .../GRPCClient/private/GRPCChannelPool.m | 4 +- src/objective-c/GRPCClient/private/GRPCHost.m | 10 +- .../InteropTestsRemoteWithCronet.m | 4 - .../tests/InteropTests/InteropTests.h | 6 - .../tests/InteropTests/InteropTests.m | 190 +-------- .../tests/InteropTests/InteropTestsRemote.m | 4 - src/objective-c/tests/MacTests/StressTests.m | 383 +----------------- src/objective-c/tests/UnitTests/APIv2Tests.m | 330 +-------------- test/cpp/interop/interop_server.cc | 3 +- 13 files changed, 33 insertions(+), 921 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index 78fe687b3d4..ae60d6208e1 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -51,9 +51,6 @@ case GRPCCompressGzip: hostConfig.compressAlgorithm = GRPC_COMPRESS_GZIP; break; - case GRPCStreamCompressGzip: - hostConfig.compressAlgorithm = GRPC_COMPRESS_STREAM_GZIP; - break; default: NSLog(@"Invalid compression algorithm"); abort(); diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.h b/src/objective-c/GRPCClient/GRPCCallOptions.h index b957e11fbea..98511e3f5cb 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.h +++ b/src/objective-c/GRPCClient/GRPCCallOptions.h @@ -156,8 +156,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { // HTTP/2 keep-alive feature. The parameter \a keepaliveInterval specifies the interval between two // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the // call should wait for PING ACK. If PING ACK is not received after this period, the call fails. -// Negative values are invalid; setting these parameters to negative value will reset the -// corresponding parameter to the internal default value. +// Negative values are not allowed. @property(readonly) NSTimeInterval keepaliveInterval; @property(readonly) NSTimeInterval keepaliveTimeout; @@ -321,7 +320,7 @@ typedef NS_ENUM(NSUInteger, GRPCTransportType) { // PING frames. The parameter \a keepaliveTimeout specifies the length of the period for which the // call should wait for PING ACK. If PING ACK is not received after this period, the call fails. // Negative values are invalid; setting these parameters to negative value will reset the -// corresponding parameter to the internal default value. +// corresponding parameter to 0. @property(readwrite) NSTimeInterval keepaliveInterval; @property(readwrite) NSTimeInterval keepaliveTimeout; diff --git a/src/objective-c/GRPCClient/GRPCCallOptions.m b/src/objective-c/GRPCClient/GRPCCallOptions.m index f02486a7c44..392e42a9d47 100644 --- a/src/objective-c/GRPCClient/GRPCCallOptions.m +++ b/src/objective-c/GRPCClient/GRPCCallOptions.m @@ -30,7 +30,7 @@ static const NSUInteger kDefaultResponseSizeLimit = 0; static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone; static const BOOL kDefaultRetryEnabled = YES; static const NSTimeInterval kDefaultKeepaliveInterval = 0; -static const NSTimeInterval kDefaultKeepaliveTimeout = -1; +static const NSTimeInterval kDefaultKeepaliveTimeout = 0; static const NSTimeInterval kDefaultConnectMinTimeout = 0; static const NSTimeInterval kDefaultConnectInitialBackoff = 0; static const NSTimeInterval kDefaultConnectMaxBackoff = 0; @@ -181,7 +181,7 @@ static BOOL areObjectsEqual(id obj1, id obj2) { _compressionAlgorithm = compressionAlgorithm; _retryEnabled = retryEnabled; _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval; - _keepaliveTimeout = keepaliveTimeout; + _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout; _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout; _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff; _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff; @@ -486,7 +486,11 @@ static BOOL areObjectsEqual(id obj1, id obj2) { } - (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout { - _keepaliveTimeout = keepaliveTimeout; + if (keepaliveTimeout < 0) { + _keepaliveTimeout = 0; + } else { + _keepaliveTimeout = keepaliveTimeout; + } } - (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout { diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 4a187ae9081..1a79fb04a0d 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -109,8 +109,6 @@ if (_callOptions.keepaliveInterval != 0) { args[@GRPC_ARG_KEEPALIVE_TIME_MS] = [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveInterval * 1000)]; - } - if (_callOptions.keepaliveTimeout >= 0) { args[@GRPC_ARG_KEEPALIVE_TIMEOUT_MS] = [NSNumber numberWithUnsignedInteger:(NSUInteger)(_callOptions.keepaliveTimeout * 1000)]; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 24ed83d3341..60a33eda824 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -118,7 +118,9 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; _lastTimedDestroy = nil; grpc_call *unmanagedCall = - [_wrappedChannel unmanagedCallWithPath:path completionQueue:queue callOptions:callOptions]; + [_wrappedChannel unmanagedCallWithPath:path + completionQueue:[GRPCCompletionQueue completionQueue] + callOptions:callOptions]; if (unmanagedCall == NULL) { NSAssert(unmanagedCall != NULL, @"Unable to create grpc_call object"); return nil; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index c4287731efd..24348c3aed7 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -105,11 +105,11 @@ static NSMutableDictionary *gHostCache; options.responseSizeLimit = _responseSizeLimitOverride; options.compressionAlgorithm = (GRPCCompressionAlgorithm)_compressAlgorithm; options.retryEnabled = _retryEnabled; - options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000.0; - options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000.0; - options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000.0; - options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000.0; - options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000.0; + options.keepaliveInterval = (NSTimeInterval)_keepaliveInterval / 1000; + options.keepaliveTimeout = (NSTimeInterval)_keepaliveTimeout / 1000; + options.connectMinTimeout = (NSTimeInterval)_minConnectTimeout / 1000; + options.connectInitialBackoff = (NSTimeInterval)_initialConnectBackoff / 1000; + options.connectMaxBackoff = (NSTimeInterval)_maxConnectBackoff / 1000; options.PEMRootCertificates = _PEMRootCertificates; options.PEMPrivateKey = _PEMPrivateKey; options.PEMCertificateChain = _PEMCertificateChain; diff --git a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m index 30741e9a0da..a2a79c46316 100644 --- a/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m +++ b/src/objective-c/tests/CronetTests/InteropTestsRemoteWithCronet.m @@ -48,10 +48,6 @@ static int32_t kRemoteInteropServerOverhead = 12; return YES; } -+ (BOOL)canRunCompressionTest { - return NO; -} - - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } diff --git a/src/objective-c/tests/InteropTests/InteropTests.h b/src/objective-c/tests/InteropTests/InteropTests.h index 0c896ae18a8..cffa90ac497 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.h +++ b/src/objective-c/tests/InteropTests/InteropTests.h @@ -64,10 +64,4 @@ */ + (BOOL)useCronet; -/** - * Whether we can run compression tests in the test suite. - */ - -+ (BOOL)canRunCompressionTest; - @end diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index e55849fecfa..91e133a1300 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -347,10 +347,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager return NO; } -+ (BOOL)canRunCompressionTest { - return YES; -} - + (void)setUp { #ifdef GRPC_COMPILE_WITH_CRONET configureCronet(); @@ -434,16 +430,10 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block BOOL messageReceived = NO; __block BOOL done = NO; - __block BOOL initialMetadataReceived = YES; NSCondition *cond = [[NSCondition alloc] init]; GRPCUnaryProtoCall *call = [_service emptyCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [cond lock]; - initialMetadataReceived = YES; - [cond unlock]; - } + responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil messageCallback:^(id message) { if (message) { id expectedResponse = [GPBEmpty message]; @@ -469,7 +459,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager while (!done && [deadline timeIntervalSinceNow] > 0) { [cond waitUntilDate:deadline]; } - XCTAssertTrue(initialMetadataReceived); XCTAssertTrue(messageReceived); XCTAssertTrue(done); [cond unlock]; @@ -1025,78 +1014,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testInitialMetadataWithV2API { - __weak XCTestExpectation *initialMetadataReceived = - [self expectationWithDescription:@"Received initial metadata."]; - __weak XCTestExpectation *closeReceived = [self expectationWithDescription:@"RPC completed."]; - - __block NSDictionary *init_md = - [NSDictionary dictionaryWithObjectsAndKeys:@"FOOBAR", @"x-grpc-test-echo-initial", nil]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.initialMetadata = init_md; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = [[self class] hostNameOverride]; - RMTSimpleRequest *request = [RMTSimpleRequest message]; - __block bool init_md_received = NO; - GRPCUnaryProtoCall *call = [_service - unaryCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - XCTAssertEqualObjects(initialMetadata[@"x-grpc-test-echo-initial"], - init_md[@"x-grpc-test-echo-initial"]); - init_md_received = YES; - [initialMetadataReceived fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - [closeReceived fulfill]; - }] - callOptions:options]; - - [call start]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testTrailingMetadataWithV2API { - // This test needs to be disabled for remote test because interop server grpc-test - // does not send trailing binary metadata. - if (isRemoteInteropTest([[self class] host])) { - return; - } - - __weak XCTestExpectation *expectation = - [self expectationWithDescription:@"Received trailing metadata."]; - const unsigned char raw_bytes[] = {0x1, 0x2, 0x3, 0x4}; - NSData *trailer_data = [NSData dataWithBytes:raw_bytes length:sizeof(raw_bytes)]; - __block NSDictionary *trailer = [NSDictionary - dictionaryWithObjectsAndKeys:trailer_data, @"x-grpc-test-echo-trailing-bin", nil]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.initialMetadata = trailer; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = [[self class] hostNameOverride]; - RMTSimpleRequest *request = [RMTSimpleRequest message]; - GRPCUnaryProtoCall *call = [_service - unaryCallWithMessage:request - responseHandler: - [[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - XCTAssertEqualObjects( - trailingMetadata[@"x-grpc-test-echo-trailing-bin"], - trailer[@"x-grpc-test-echo-trailing-bin"]); - [expectation fulfill]; - }] - callOptions:options]; - [call start]; - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - - (void)testCancelAfterFirstResponseRPC { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = @@ -1231,7 +1148,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)RPCWithCompressMethod:(GRPCCompressionAlgorithm)compressMethod { +- (void)testCompressedUnaryRPC { + // This test needs to be disabled for remote test because interop server grpc-test + // does not support compression. + if (isRemoteInteropTest([[self class] host])) { + return; + } + XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"LargeUnary"]; RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -1239,7 +1162,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; request.expectCompressed.value = YES; - [GRPCCall setDefaultCompressMethod:compressMethod forhost:[[self class] host]]; + [GRPCCall setDefaultCompressMethod:GRPCCompressGzip forhost:[[self class] host]]; [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { @@ -1256,67 +1179,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)RPCWithCompressMethodWithV2API:(GRPCCompressionAlgorithm)compressMethod { - __weak XCTestExpectation *expectMessage = - [self expectationWithDescription:@"Reived response from server."]; - __weak XCTestExpectation *expectComplete = [self expectationWithDescription:@"RPC completed."]; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.responseType = RMTPayloadType_Compressable; - request.responseSize = 314159; - request.payload.body = [NSMutableData dataWithLength:271828]; - request.expectCompressed.value = YES; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = [[self class] hostNameOverride]; - options.compressionAlgorithm = compressMethod; - - GRPCUnaryProtoCall *call = [_service - unaryCallWithMessage:request - responseHandler:[[InteropTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - XCTAssertNotNil(message); - if (message) { - RMTSimpleResponse *expectedResponse = - [RMTSimpleResponse message]; - expectedResponse.payload.type = RMTPayloadType_Compressable; - expectedResponse.payload.body = - [NSMutableData dataWithLength:314159]; - XCTAssertEqualObjects(message, expectedResponse); - - [expectMessage fulfill]; - } - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - [expectComplete fulfill]; - }] - callOptions:options]; - [call start]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testCompressedUnaryRPC { - if ([[self class] canRunCompressionTest]) { - for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate; - compress <= GRPCStreamCompressGzip; ++compress) { - [self RPCWithCompressMethod:compress]; - } - } -} - -- (void)testCompressedUnaryRPCWithV2API { - if ([[self class] canRunCompressionTest]) { - for (GRPCCompressionAlgorithm compress = GRPCCompressDeflate; - compress <= GRPCStreamCompressGzip; ++compress) { - [self RPCWithCompressMethodWithV2API:compress]; - } - } -} - #ifndef GRPC_COMPILE_WITH_CRONET - (void)testKeepalive { XCTAssertNotNil([[self class] host]); @@ -1358,40 +1220,6 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } - -- (void)testKeepaliveWithV2API { - XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Keepalive"]; - - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = self.class.transportType; - options.PEMRootCertificates = self.class.PEMRootCertificates; - options.hostNameOverride = [[self class] hostNameOverride]; - options.keepaliveInterval = 1.5; - options.keepaliveTimeout = 0; - - id request = - [RMTStreamingOutputCallRequest messageWithPayloadSize:@21782 requestedResponseSize:@31415]; - - __block GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^( - NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNotNil(error); - XCTAssertEqual( - error.code, - GRPC_STATUS_UNAVAILABLE); - [expectation fulfill]; - }] - callOptions:options]; - [call start]; - [call writeMessage:request]; - - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} #endif - (void)testDefaultInterceptor { diff --git a/src/objective-c/tests/InteropTests/InteropTestsRemote.m b/src/objective-c/tests/InteropTests/InteropTestsRemote.m index 7bd5b28780c..c1cd9b81efc 100644 --- a/src/objective-c/tests/InteropTests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTests/InteropTestsRemote.m @@ -49,10 +49,6 @@ static int32_t kRemoteInteropServerOverhead = 12; return nil; } -+ (BOOL)canRunCompressionTest { - return NO; -} - - (int32_t)encodingOverhead { return kRemoteInteropServerOverhead; // bytes } diff --git a/src/objective-c/tests/MacTests/StressTests.m b/src/objective-c/tests/MacTests/StressTests.m index 7475dc77fcc..22174b58665 100644 --- a/src/objective-c/tests/MacTests/StressTests.m +++ b/src/objective-c/tests/MacTests/StressTests.m @@ -29,7 +29,7 @@ #import #import -#define TEST_TIMEOUT 64 +#define TEST_TIMEOUT 32 extern const char *kCFStreamVarName; @@ -136,11 +136,7 @@ extern const char *kCFStreamVarName; return GRPCTransportTypeChttp2BoringSSL; } -- (int)getRandomNumberBetween:(int)min max:(int)max { - return min + arc4random_uniform((max - min + 1)); -} - -- (void)testNetworkFlapOnUnaryCallWithV2API { +- (void)testNetworkFlapWithV2API { NSMutableArray *completeExpectations = [NSMutableArray array]; NSMutableArray *calls = [NSMutableArray array]; int num_rpcs = 100; @@ -179,7 +175,6 @@ extern const char *kCFStreamVarName; UTF8String]); address_removed = YES; } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); system([ [NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] @@ -201,241 +196,7 @@ extern const char *kCFStreamVarName; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testNetworkFlapOnClientStreamingCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - __block BOOL address_removed = FALSE; - __block BOOL address_readded = FALSE; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - GRPCStreamingProtoCall *call = [_service - streamingInputCallWithResponseHandler: - [[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - @synchronized(self) { - if (error == nil && !address_removed) { - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 -alias %@", - [[self class] hostAddress]] - UTF8String]); - address_removed = YES; - } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 alias %@", - [[self class] hostAddress]] - UTF8String]); - address_readded = YES; - } - } - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - RMTStreamingInputCallRequest *request1 = [RMTStreamingInputCallRequest message]; - request1.payload.body = [NSMutableData dataWithLength:27182]; - RMTStreamingInputCallRequest *request2 = [RMTStreamingInputCallRequest message]; - request2.payload.body = [NSMutableData dataWithLength:8]; - - [call writeMessage:request1]; - [NSThread sleepForTimeInterval:0.1f]; - [call writeMessage:request2]; - [call finish]; - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testNetworkFlapOnServerStreamingCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - __block BOOL address_removed = FALSE; - __block BOOL address_readded = FALSE; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - for (int i = 0; i < 5; i++) { - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 10000; - [request.responseParametersArray addObject:parameters]; - } - - request.payload.body = [NSMutableData dataWithLength:100]; - - GRPCUnaryProtoCall *call = [_service - streamingOutputCallWithMessage:request - responseHandler: - [[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - @synchronized(self) { - if (error == nil && !address_removed) { - system([[NSString - stringWithFormat: - @"sudo ifconfig lo0 -alias %@", - [[self class] hostAddress]] - UTF8String]); - address_removed = YES; - } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); - system([[NSString - stringWithFormat: - @"sudo ifconfig lo0 alias %@", - [[self class] hostAddress]] - UTF8String]); - address_readded = YES; - } - } - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - [NSThread sleepForTimeInterval:0.1f]; - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testNetworkFlapOnHalfDuplexCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - __block BOOL address_removed = FALSE; - __block BOOL address_readded = FALSE; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - GRPCStreamingProtoCall *call = [_service - halfDuplexCallWithResponseHandler: - [[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - @synchronized(self) { - if (error == nil && !address_removed) { - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 -alias %@", - [[self class] hostAddress]] - UTF8String]); - address_removed = YES; - } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 alias %@", - [[self class] hostAddress]] - UTF8String]); - address_readded = YES; - } - } - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - RMTStreamingOutputCallRequest *request1 = [RMTStreamingOutputCallRequest message]; - RMTStreamingOutputCallRequest *request2 = [RMTStreamingOutputCallRequest message]; - for (int i = 0; i < 5; i++) { - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 1000; - [request1.responseParametersArray addObject:parameters]; - [request2.responseParametersArray addObject:parameters]; - } - - request1.payload.body = [NSMutableData dataWithLength:100]; - request2.payload.body = [NSMutableData dataWithLength:100]; - - [call writeMessage:request1]; - [NSThread sleepForTimeInterval:0.1f]; - [call writeMessage:request2]; - [call finish]; - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testNetworkFlapOnFullDuplexCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - __block BOOL address_removed = FALSE; - __block BOOL address_readded = FALSE; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler: - [[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - @synchronized(self) { - if (error == nil && !address_removed) { - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 -alias %@", - [[self class] hostAddress]] - UTF8String]); - address_removed = YES; - } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); - system([[NSString - stringWithFormat:@"sudo ifconfig lo0 alias %@", - [[self class] hostAddress]] - UTF8String]); - address_readded = YES; - } - } - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 1000; - for (int i = 0; i < 5; i++) { - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:100]; - [call writeMessage:request]; - } - [call finish]; - [NSThread sleepForTimeInterval:0.1f]; - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testNetworkFlapOnUnaryCallWithV1API { +- (void)testNetworkFlapWithV1API { NSMutableArray *completeExpectations = [NSMutableArray array]; int num_rpcs = 100; __block BOOL address_removed = FALSE; @@ -459,7 +220,6 @@ extern const char *kCFStreamVarName; UTF8String]); address_removed = YES; } else if (error != nil && !address_readded) { - XCTAssertTrue(address_removed); system([[NSString stringWithFormat:@"sudo ifconfig lo0 alias %@", [[self class] hostAddress]] UTF8String]); @@ -474,141 +234,4 @@ extern const char *kCFStreamVarName; } } -- (void)testTimeoutOnFullDuplexCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - options.transportType = [[self class] transportType]; - options.PEMRootCertificates = [[self class] PEMRootCertificates]; - options.hostNameOverride = [[self class] hostNameOverride]; - options.timeout = 0.3; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler: - [[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - if (error != nil) { - XCTAssertEqual(error.code, GRPC_STATUS_DEADLINE_EXCEEDED); - } - [completeExpectations[i] fulfill]; - }] - callOptions:options]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 1000; - // delay response by 100-200 milliseconds - parameters.intervalUs = [self getRandomNumberBetween:100 * 1000 max:200 * 1000]; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:100]; - - [call writeMessage:request]; - [call writeMessage:request]; - [call finish]; - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testServerStreamingCallSlowClientWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - for (int i = 0; i < 5; i++) { - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 10000; - [request.responseParametersArray addObject:parameters]; - [request.responseParametersArray addObject:parameters]; - [request.responseParametersArray addObject:parameters]; - [request.responseParametersArray addObject:parameters]; - [request.responseParametersArray addObject:parameters]; - } - - request.payload.body = [NSMutableData dataWithLength:100]; - - GRPCUnaryProtoCall *call = [_service - streamingOutputCallWithMessage:request - responseHandler:[[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:^(id message) { - // inject a delay - [NSThread sleepForTimeInterval:0.5f]; - } - closeCallback:^(NSDictionary *trailingMetadata, - NSError *error) { - XCTAssertNil(error, @"Unexpected error: %@", error); - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - dispatch_async(q, ^{ - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - }); - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - -- (void)testCancelOnFullDuplexCallWithV2API { - NSMutableArray *completeExpectations = [NSMutableArray array]; - NSMutableArray *calls = [NSMutableArray array]; - int num_rpcs = 100; - dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - - GRPCStreamingProtoCall *call = [_service - fullDuplexCallWithResponseHandler:[[MacTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:nil - messageCallback:nil - closeCallback:^( - NSDictionary *trailingMetadata, - NSError *error) { - [completeExpectations[i] fulfill]; - }] - callOptions:nil]; - [calls addObject:call]; - } - - for (int i = 0; i < num_rpcs; ++i) { - GRPCStreamingProtoCall *call = calls[i]; - [call start]; - dispatch_async(q, ^{ - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = 1000; - for (int i = 0; i < 100; i++) { - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - [request.responseParametersArray addObject:parameters]; - [call writeMessage:request]; - } - [NSThread sleepForTimeInterval:0.01f]; - [call cancel]; - }); - } - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; -} - @end diff --git a/src/objective-c/tests/UnitTests/APIv2Tests.m b/src/objective-c/tests/UnitTests/APIv2Tests.m index 066800613f6..db293750ca3 100644 --- a/src/objective-c/tests/UnitTests/APIv2Tests.m +++ b/src/objective-c/tests/UnitTests/APIv2Tests.m @@ -21,11 +21,6 @@ #import #import -#import "../../GRPCClient/private/GRPCCallInternal.h" -#import "../../GRPCClient/private/GRPCChannel.h" -#import "../../GRPCClient/private/GRPCChannelPool.h" -#import "../../GRPCClient/private/GRPCWrappedCall.h" - #include #include @@ -53,41 +48,12 @@ static const int kSimpleDataLength = 100; static const NSTimeInterval kTestTimeout = 8; static const NSTimeInterval kInvertedTimeout = 2; -// Reveal the _class ivars for testing access +// Reveal the _class ivar for testing access @interface GRPCCall2 () { - @public - id _firstInterceptor; -} -@end - -@interface GRPCCall2Internal () { @public GRPCCall *_call; } -@end - -@interface GRPCCall () { - @public - GRPCWrappedCall *_wrappedCall; -} -@end - -@interface GRPCWrappedCall () { - @public - GRPCPooledChannel *_pooledChannel; -} -@end - -@interface GRPCPooledChannel () { - @public - GRPCChannel *_wrappedChannel; -} -@end -@interface GRPCChannel () { - @public - grpc_channel *_unmanagedChannel; -} @end // Convenience class to use blocks as callbacks @@ -182,7 +148,6 @@ static const NSTimeInterval kInvertedTimeout = 2; kOutputStreamingCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"StreamingOutputCall"]; - kFullDuplexCallMethod = [[GRPCProtoMethod alloc] initWithPackage:kPackage service:kService method:@"FullDuplexCall"]; } @@ -214,7 +179,7 @@ static const NSTimeInterval kInvertedTimeout = 2; closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { trailing_md = trailingMetadata; if (error) { - XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated, + XCTAssertEqual(error.code, 16, @"Finished with unexpected error: %@", error); XCTAssertEqualObjects(init_md, error.userInfo[kGRPCHeadersKey]); @@ -794,7 +759,7 @@ static const NSTimeInterval kInvertedTimeout = 2; } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { XCTAssertNotNil(error, @"Expecting non-nil error"); - XCTAssertEqual(error.code, GRPCErrorCodeUnknown); + XCTAssertEqual(error.code, 2); [completion fulfill]; }] callOptions:options]; @@ -805,293 +770,4 @@ static const NSTimeInterval kInvertedTimeout = 2; [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; } -- (void)testAdditionalChannelArgs { - __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."]; - - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kUnaryCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; - // set max message length = 1 byte. - options.additionalChannelArgs = - [NSDictionary dictionaryWithObjectsAndKeys:@1, @GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, nil]; - options.transportType = GRPCTransportTypeInsecure; - - RMTSimpleRequest *request = [RMTSimpleRequest message]; - request.payload.body = [NSMutableData dataWithLength:options.responseSizeLimit]; - - GRPCCall2 *call = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] initWithInitialMetadataCallback:nil - messageCallback:^(NSData *data) { - XCTFail(@"Received unexpected message"); - } - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertNotNil(error, @"Expecting non-nil error"); - NSLog(@"Got error: %@", error); - XCTAssertEqual(error.code, GRPCErrorCodeResourceExhausted, - @"Finished with unexpected error: %@", error); - - [completion fulfill]; - }] - callOptions:options]; - [call writeData:[request data]]; - [call start]; - [call finish]; - - [self waitForExpectationsWithTimeout:kTestTimeout handler:nil]; -} - -- (void)testChannelReuseIdentical { - __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; - __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; - NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; - __weak XCTestExpectation *metadata1 = - [self expectationWithDescription:@"Received initial metadata for RPC1."]; - __weak XCTestExpectation *metadata2 = - [self expectationWithDescription:@"Received initial metadata for RPC2."]; - NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = kSimpleDataLength; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; - - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; - callOptions.transportType = GRPCTransportTypeInsecure; - GRPCCall2 *call1 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata1 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion1 fulfill]; - }] - callOptions:callOptions]; - GRPCCall2 *call2 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata2 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion2 fulfill]; - }] - callOptions:callOptions]; - [call1 start]; - [call2 start]; - [call1 writeData:[request data]]; - [call2 writeData:[request data]]; - [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; - GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; - GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; - XCTAssertEqual( - internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, - internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); - [call1 finish]; - [call2 finish]; - [self waitForExpectations:rpcDone timeout:kTestTimeout]; -} - -- (void)testChannelReuseDifferentCallSafety { - __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; - __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; - NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; - __weak XCTestExpectation *metadata1 = - [self expectationWithDescription:@"Received initial metadata for RPC1."]; - __weak XCTestExpectation *metadata2 = - [self expectationWithDescription:@"Received initial metadata for RPC2."]; - NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = kSimpleDataLength; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; - - GRPCRequestOptions *requestOptions1 = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - GRPCRequestOptions *requestOptions2 = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyIdempotentRequest]; - - GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; - callOptions.transportType = GRPCTransportTypeInsecure; - GRPCCall2 *call1 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions1 - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata1 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion1 fulfill]; - }] - callOptions:callOptions]; - GRPCCall2 *call2 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions2 - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata2 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion2 fulfill]; - }] - callOptions:callOptions]; - [call1 start]; - [call2 start]; - [call1 writeData:[request data]]; - [call2 writeData:[request data]]; - [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; - GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; - GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; - XCTAssertEqual( - internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, - internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); - [call1 finish]; - [call2 finish]; - [self waitForExpectations:rpcDone timeout:kTestTimeout]; -} - -- (void)testChannelReuseDifferentHost { - __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; - __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; - NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; - __weak XCTestExpectation *metadata1 = - [self expectationWithDescription:@"Received initial metadata for RPC1."]; - __weak XCTestExpectation *metadata2 = - [self expectationWithDescription:@"Received initial metadata for RPC2."]; - NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = kSimpleDataLength; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; - - GRPCRequestOptions *requestOptions1 = - [[GRPCRequestOptions alloc] initWithHost:@"[::1]:5050" - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - GRPCRequestOptions *requestOptions2 = - [[GRPCRequestOptions alloc] initWithHost:@"127.0.0.1:5050" - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - - GRPCMutableCallOptions *callOptions = [[GRPCMutableCallOptions alloc] init]; - callOptions.transportType = GRPCTransportTypeInsecure; - - GRPCCall2 *call1 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions1 - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata1 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion1 fulfill]; - }] - callOptions:callOptions]; - GRPCCall2 *call2 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions2 - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata2 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion2 fulfill]; - }] - callOptions:callOptions]; - [call1 start]; - [call2 start]; - [call1 writeData:[request data]]; - [call2 writeData:[request data]]; - [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; - GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; - GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; - XCTAssertNotEqual( - internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, - internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); - [call1 finish]; - [call2 finish]; - [self waitForExpectations:rpcDone timeout:kTestTimeout]; -} - -- (void)testChannelReuseDifferentChannelArgs { - __weak XCTestExpectation *completion1 = [self expectationWithDescription:@"RPC1 completed."]; - __weak XCTestExpectation *completion2 = [self expectationWithDescription:@"RPC2 completed."]; - NSArray *rpcDone = [NSArray arrayWithObjects:completion1, completion2, nil]; - __weak XCTestExpectation *metadata1 = - [self expectationWithDescription:@"Received initial metadata for RPC1."]; - __weak XCTestExpectation *metadata2 = - [self expectationWithDescription:@"Received initial metadata for RPC2."]; - NSArray *initialMetadataDone = [NSArray arrayWithObjects:metadata1, metadata2, nil]; - - RMTStreamingOutputCallRequest *request = [RMTStreamingOutputCallRequest message]; - RMTResponseParameters *parameters = [RMTResponseParameters message]; - parameters.size = kSimpleDataLength; - [request.responseParametersArray addObject:parameters]; - request.payload.body = [NSMutableData dataWithLength:kSimpleDataLength]; - - GRPCRequestOptions *requestOptions = - [[GRPCRequestOptions alloc] initWithHost:kHostAddress - path:kFullDuplexCallMethod.HTTPPath - safety:GRPCCallSafetyDefault]; - GRPCMutableCallOptions *callOptions1 = [[GRPCMutableCallOptions alloc] init]; - callOptions1.transportType = GRPCTransportTypeInsecure; - GRPCMutableCallOptions *callOptions2 = [[GRPCMutableCallOptions alloc] init]; - callOptions2.transportType = GRPCTransportTypeInsecure; - callOptions2.channelID = 2; - - GRPCCall2 *call1 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata1 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion1 fulfill]; - }] - callOptions:callOptions1]; - GRPCCall2 *call2 = [[GRPCCall2 alloc] - initWithRequestOptions:requestOptions - responseHandler:[[ClientTestsBlockCallbacks alloc] - initWithInitialMetadataCallback:^(NSDictionary *initialMetadata) { - [metadata2 fulfill]; - } - messageCallback:nil - closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - [completion2 fulfill]; - }] - callOptions:callOptions2]; - [call1 start]; - [call2 start]; - [call1 writeData:[request data]]; - [call2 writeData:[request data]]; - [self waitForExpectations:initialMetadataDone timeout:kTestTimeout]; - GRPCCall2Internal *internalCall1 = call1->_firstInterceptor; - GRPCCall2Internal *internalCall2 = call2->_firstInterceptor; - XCTAssertNotEqual( - internalCall1->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel, - internalCall2->_call->_wrappedCall->_pooledChannel->_wrappedChannel->_unmanagedChannel); - [call1 finish]; - [call2 finish]; - [self waitForExpectations:rpcDone timeout:kTestTimeout]; -} - @end diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index cf55efa5409..6570bbf9696 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -118,8 +118,7 @@ bool CheckExpectedCompression(const ServerContext& context, "Expected compression but got uncompressed request from client."); return false; } - if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS) && - received_compression != GRPC_COMPRESS_STREAM_GZIP) { + if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)) { gpr_log(GPR_ERROR, "Failure: Requested compression in a compressable request, but " "compression bit in message flags not set."); From e00aeaeb2696ef710c0faed713b4ed5ace87b330 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Jun 2019 23:57:54 +0000 Subject: [PATCH 315/676] Fix bugs with libuv cares integration on Windows --- src/core/lib/iomgr/port.h | 6 +++++- src/core/lib/iomgr/tcp_uv.cc | 11 +++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 605692ac0d6..63a0269ed62 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -26,6 +26,11 @@ #define GRPC_CUSTOM_SOCKET #endif #endif +/* This needs to be separate from the other conditions because it needs to + * apply to custom sockets too */ +#ifdef GPR_WINDOWS +#define GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY 1 +#endif #if defined(GRPC_CUSTOM_SOCKET) // Do Nothing #elif defined(GPR_MANYLINUX1) @@ -45,7 +50,6 @@ #define GRPC_WINSOCK_SOCKET 1 #define GRPC_WINDOWS_SOCKETUTILS 1 #define GRPC_WINDOWS_SOCKET_ARES_EV_DRIVER 1 -#define GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY 1 #elif defined(GPR_ANDROID) #define GRPC_HAVE_IPV6_RECVPKTINFO 1 #define GRPC_HAVE_IP_PKTINFO 1 diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc index e53ff472fef..f0847a195ca 100644 --- a/src/core/lib/iomgr/tcp_uv.cc +++ b/src/core/lib/iomgr/tcp_uv.cc @@ -53,7 +53,7 @@ typedef struct uv_socket_t { char* read_buf; size_t read_len; - bool pending_connection; + int pending_connections; grpc_custom_socket* accept_socket; grpc_error* accept_error; @@ -206,7 +206,7 @@ static grpc_error* uv_socket_init_helper(uv_socket_t* uv_socket, int domain) { // Node uses a garbage collector to call destructors, so we don't // want to hold the uv loop open with active gRPC objects. uv_unref((uv_handle_t*)uv_socket->handle); - uv_socket->pending_connection = false; + uv_socket->pending_connections = 0; uv_socket->accept_socket = nullptr; uv_socket->accept_error = GRPC_ERROR_NONE; return GRPC_ERROR_NONE; @@ -243,14 +243,14 @@ static grpc_error* uv_socket_getsockname(grpc_custom_socket* socket, static void accept_new_connection(grpc_custom_socket* socket) { uv_socket_t* uv_socket = (uv_socket_t*)socket->impl; - if (!uv_socket->pending_connection || !uv_socket->accept_socket) { + if (uv_socket->pending_connections == 0 || !uv_socket->accept_socket) { return; } grpc_custom_socket* new_socket = uv_socket->accept_socket; grpc_error* error = uv_socket->accept_error; uv_socket->accept_socket = nullptr; uv_socket->accept_error = GRPC_ERROR_NONE; - uv_socket->pending_connection = false; + uv_socket->pending_connections -= 1; if (uv_socket->accept_error != GRPC_ERROR_NONE) { uv_stream_t dummy_handle; uv_accept((uv_stream_t*)uv_socket->handle, &dummy_handle); @@ -270,8 +270,6 @@ static void accept_new_connection(grpc_custom_socket* socket) { static void uv_on_connect(uv_stream_t* server, int status) { grpc_custom_socket* socket = (grpc_custom_socket*)server->data; uv_socket_t* uv_socket = (uv_socket_t*)socket->impl; - GPR_ASSERT(!uv_socket->pending_connection); - uv_socket->pending_connection = true; if (status < 0) { switch (status) { case UV_EINTR: @@ -281,6 +279,7 @@ static void uv_on_connect(uv_stream_t* server, int status) { uv_socket->accept_error = tcp_error_create("accept failed", status); } } + uv_socket->pending_connections += 1; accept_new_connection(socket); } From 16e66c83070f2900f520520ab9ce48a4ce137cb0 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 13 Jun 2019 08:16:03 -0700 Subject: [PATCH 316/676] Fix debug logging of stream refcounts. --- src/core/ext/filters/client_channel/client_channel.cc | 7 +++++++ src/core/lib/transport/transport.cc | 2 +- src/core/lib/transport/transport.h | 10 ++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 81562ab2107..0b612e67a33 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1180,6 +1180,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) interested_parties_(grpc_pollset_set_create()), subchannel_pool_(GetSubchannelPool(args->channel_args)), disconnect_error_(GRPC_ERROR_NONE) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p: creating client_channel for channel stack %p", + this, owning_stack_); + } // Initialize data members. grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "client_channel"); @@ -1259,6 +1263,9 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) } ChannelData::~ChannelData() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p: destroying channel", this); + } if (resolving_lb_policy_ != nullptr) { grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(), interested_parties_); diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 29c1e561891..80ffabce0e5 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -90,7 +90,7 @@ void grpc_stream_ref_init(grpc_stream_refcount* refcount, int initial_refs, #endif GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); - new (&refcount->refs) grpc_core::RefCount(); + new (&refcount->refs) grpc_core::RefCount(1, &grpc_trace_stream_refcount); new (&refcount->slice_refcount) grpc_slice_refcount( grpc_slice_refcount::Type::REGULAR, &refcount->refs, slice_stream_destroy, refcount, &refcount->slice_refcount); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index a6a6e904f08..17608f4bc60 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -80,11 +80,13 @@ inline void grpc_stream_ref(grpc_stream_refcount* refcount, gpr_log(GPR_DEBUG, "%s %p:%p REF %s", refcount->object_type, refcount, refcount->destroy.cb_arg, reason); } + refcount->refs.RefNonZero(DEBUG_LOCATION, reason); +} #else inline void grpc_stream_ref(grpc_stream_refcount* refcount) { -#endif refcount->refs.RefNonZero(); } +#endif void grpc_stream_destroy(grpc_stream_refcount* refcount); @@ -95,13 +97,17 @@ inline void grpc_stream_unref(grpc_stream_refcount* refcount, gpr_log(GPR_DEBUG, "%s %p:%p UNREF %s", refcount->object_type, refcount, refcount->destroy.cb_arg, reason); } + if (GPR_UNLIKELY(refcount->refs.Unref(DEBUG_LOCATION, reason))) { + grpc_stream_destroy(refcount); + } +} #else inline void grpc_stream_unref(grpc_stream_refcount* refcount) { -#endif if (GPR_UNLIKELY(refcount->refs.Unref())) { grpc_stream_destroy(refcount); } } +#endif /* Wrap a buffer that is owned by some stream object into a slice that shares the same refcount */ From 9417a6a08075e3a898072c8742fe4e207ce601d6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 13 Jun 2019 08:43:56 -0700 Subject: [PATCH 317/676] Various LB policy tracing improvements. --- .../ext/filters/client_channel/lb_policy.h | 2 + .../lb_policy/pick_first/pick_first.cc | 14 +-- .../lb_policy/round_robin/round_robin.cc | 4 +- .../client_channel/lb_policy/xds/xds.cc | 100 ++++++++++++++---- 4 files changed, 93 insertions(+), 27 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index d508932015d..f98a41dee07 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -292,6 +292,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { explicit QueuePicker(RefCountedPtr parent) : parent_(std::move(parent)) {} + ~QueuePicker() { parent_.reset(DEBUG_LOCATION, "QueuePicker"); } + PickResult Pick(PickArgs args) override; private: diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index e4b58eb7558..00036d8be64 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -329,7 +329,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( } else { p->channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, - UniquePtr(New(p->Ref()))); + UniquePtr( + New(p->Ref(DEBUG_LOCATION, "QueuePicker")))); } } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { @@ -342,8 +343,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, - UniquePtr(New(p->Ref()))); + GRPC_CHANNEL_IDLE, UniquePtr(New( + p->Ref(DEBUG_LOCATION, "QueuePicker")))); } else { // This is unlikely but can happen when a subchannel has been asked // to reconnect by a different channel and this channel has dropped @@ -354,8 +355,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( connected_subchannel()->Ref()))); } else { // CONNECTING p->channel_control_helper()->UpdateState( - connectivity_state, - UniquePtr(New(p->Ref()))); + connectivity_state, UniquePtr(New( + p->Ref(DEBUG_LOCATION, "QueuePicker")))); } } } @@ -411,7 +412,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( if (subchannel_list() == p->subchannel_list_.get()) { p->channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, - UniquePtr(New(p->Ref()))); + UniquePtr( + New(p->Ref(DEBUG_LOCATION, "QueuePicker")))); } break; } diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 17c65d8b551..c6655c7d9bb 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -323,8 +323,8 @@ void RoundRobin::RoundRobinSubchannelList:: } else if (num_connecting_ > 0) { /* 2) CONNECTING */ p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, - UniquePtr(New(p->Ref()))); + GRPC_CHANNEL_CONNECTING, UniquePtr(New( + p->Ref(DEBUG_LOCATION, "QueuePicker")))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ grpc_error* error = diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 136d85bba14..e790ec25520 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -333,6 +333,8 @@ class XdsLb : public LoadBalancingPolicy { explicit FallbackHelper(RefCountedPtr parent) : parent_(std::move(parent)) {} + ~FallbackHelper() { parent_.reset(DEBUG_LOCATION, "FallbackHelper"); } + RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, @@ -377,19 +379,30 @@ class XdsLb : public LoadBalancingPolicy { strcmp(subzone_.get(), other.subzone_.get()) == 0; } + const char* AsHumanReadableString() { + if (human_readable_string_ == nullptr) { + char* tmp; + gpr_asprintf(&tmp, "{region=\"%s\", zone=\"%s\", subzone=\"%s\"}", + region_.get(), zone_.get(), subzone_.get()); + human_readable_string_.reset(tmp); + } + return human_readable_string_.get(); + } + private: UniquePtr region_; UniquePtr zone_; UniquePtr subzone_; + UniquePtr human_readable_string_; }; class LocalityMap { public: class LocalityEntry : public InternallyRefCounted { public: - LocalityEntry(RefCountedPtr parent, uint32_t locality_weight) - : parent_(std::move(parent)), locality_weight_(locality_weight) {} - ~LocalityEntry() = default; + LocalityEntry(RefCountedPtr parent, + RefCountedPtr name, uint32_t locality_weight); + ~LocalityEntry(); void UpdateLocked(xds_grpclb_serverlist* serverlist, LoadBalancingPolicy::Config* child_policy_config, @@ -404,6 +417,8 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} + ~Helper() { entry_.reset(DEBUG_LOCATION, "Helper"); } + RefCountedPtr CreateSubchannel( const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, @@ -428,9 +443,10 @@ class XdsLb : public LoadBalancingPolicy { grpc_channel_args* CreateChildPolicyArgsLocked( const grpc_channel_args* args); + RefCountedPtr parent_; + RefCountedPtr name_; OrphanablePtr child_policy_; OrphanablePtr pending_child_policy_; - RefCountedPtr parent_; RefCountedPtr picker_ref_; grpc_connectivity_state connectivity_state_; uint32_t locality_weight_; @@ -743,7 +759,7 @@ ServerAddressList ProcessServerlist(const xds_grpclb_serverlist* serverlist) { XdsLb::BalancerChannelState::BalancerChannelState( const char* balancer_name, const grpc_channel_args& args, - grpc_core::RefCountedPtr parent_xdslb_policy) + RefCountedPtr parent_xdslb_policy) : InternallyRefCounted(&grpc_lb_xds_trace), xdslb_policy_(std::move(parent_xdslb_policy)), lb_call_backoff_( @@ -763,6 +779,7 @@ XdsLb::BalancerChannelState::BalancerChannelState( } XdsLb::BalancerChannelState::~BalancerChannelState() { + xdslb_policy_.reset(DEBUG_LOCATION, "BalancerChannelState"); grpc_channel_destroy(channel_); } @@ -1414,12 +1431,18 @@ XdsLb::XdsLb(Args args) } XdsLb::~XdsLb() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] destroying xds LB policy", this); + } gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); locality_serverlist_.clear(); } void XdsLb::ShutdownLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] shutting down", this); + } shutting_down_ = true; if (fallback_at_startup_checks_pending_) { grpc_timer_cancel(&lb_fallback_timer_); @@ -1486,8 +1509,9 @@ void XdsLb::ProcessAddressesAndChannelArgsLocked( } if (create_lb_channel) { OrphanablePtr lb_chand = - MakeOrphanable(balancer_name_.get(), - *lb_channel_args, Ref()); + MakeOrphanable( + balancer_name_.get(), *lb_channel_args, + Ref(DEBUG_LOCATION, "BalancerChannelState")); if (lb_chand_ == nullptr || !lb_chand_->HasActiveCall()) { GPR_ASSERT(pending_lb_chand_ == nullptr); // If we do not have a working LB channel yet, use the newly created one. @@ -1676,7 +1700,8 @@ void XdsLb::UpdateFallbackPolicyLocked() { OrphanablePtr XdsLb::CreateFallbackPolicyLocked( const char* name, const grpc_channel_args* args) { - FallbackHelper* helper = New(Ref()); + FallbackHelper* helper = + New(Ref(DEBUG_LOCATION, "FallbackHelper")); LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.args = args; @@ -1739,7 +1764,9 @@ void XdsLb::LocalityMap::UpdateLocked( auto iter = map_.find(locality_serverlist[i]->locality_name); if (iter == map_.end()) { OrphanablePtr new_entry = MakeOrphanable( - parent->Ref(), locality_serverlist[i]->locality_weight); + parent->Ref(DEBUG_LOCATION, "LocalityEntry"), + locality_serverlist[i]->locality_name, + locality_serverlist[i]->locality_weight); iter = map_.emplace(locality_serverlist[i]->locality_name, std::move(new_entry)) .first; @@ -1764,6 +1791,27 @@ void XdsLb::LocalityMap::ResetBackoffLocked() { // XdsLb::LocalityMap::LocalityEntry // +XdsLb::LocalityMap::LocalityEntry::LocalityEntry( + RefCountedPtr parent, RefCountedPtr name, + uint32_t locality_weight) + : parent_(std::move(parent)), + name_(std::move(name)), + locality_weight_(locality_weight) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] created LocalityEntry %p for %s", + parent_.get(), this, name_->AsHumanReadableString()); + } +} + +XdsLb::LocalityMap::LocalityEntry::~LocalityEntry() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] LocalityEntry %p %s: destroying locality entry", + parent_.get(), this, name_->AsHumanReadableString()); + } + parent_.reset(DEBUG_LOCATION, "LocalityEntry"); +} + grpc_channel_args* XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked( const grpc_channel_args* args_in) { @@ -1785,7 +1833,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyArgsLocked( OrphanablePtr XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( const char* name, const grpc_channel_args* args) { - Helper* helper = New(this->Ref()); + Helper* helper = New(this->Ref(DEBUG_LOCATION, "Helper")); LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = parent_->combiner(); lb_policy_args.args = args; @@ -1795,13 +1843,16 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( name, std::move(lb_policy_args)); if (GPR_UNLIKELY(lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "[xdslb %p] Failure creating child policy %s", this, - name); + gpr_log(GPR_ERROR, + "[xdslb %p] LocalityEntry %p %s: failure creating child policy %s", + parent_.get(), this, name_->AsHumanReadableString(), name); return nullptr; } helper->set_child(lb_policy.get()); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { - gpr_log(GPR_INFO, "[xdslb %p] Created new child policy %s (%p)", this, name, + gpr_log(GPR_INFO, + "[xdslb %p] LocalityEntry %p %s: Created new child policy %s (%p)", + parent_.get(), this, name_->AsHumanReadableString(), name, lb_policy.get()); } // Add the xDS's interested_parties pollset_set to that of the newly created @@ -1892,7 +1943,9 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( // If child_policy_ is null, we set it (case 1), else we set // pending_child_policy_ (cases 2b and 3b). if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { - gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, + gpr_log(GPR_INFO, + "[xdslb %p] LocalityEntry %p %s: Creating new %schild policy %s", + parent_.get(), this, name_->AsHumanReadableString(), child_policy_ == nullptr ? "" : "pending ", child_policy_name); } auto& lb_policy = @@ -1910,7 +1963,9 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( GPR_ASSERT(policy_to_update != nullptr); // Update the policy. if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { - gpr_log(GPR_INFO, "[xdslb %p] Updating %schild policy %p", this, + gpr_log(GPR_INFO, + "[xdslb %p] LocalityEntry %p %s: Updating %schild policy %p", + parent_.get(), this, name_->AsHumanReadableString(), policy_to_update == pending_child_policy_.get() ? "pending " : "", policy_to_update); } @@ -1918,17 +1973,22 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( } void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] LocalityEntry %p %s: shutting down locality entry", + parent_.get(), this, name_->AsHumanReadableString()); + } // Remove the child policy's interested_parties pollset_set from the // xDS policy. grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), parent_->interested_parties()); + child_policy_.reset(); if (pending_child_policy_ != nullptr) { grpc_pollset_set_del_pollset_set( pending_child_policy_->interested_parties(), parent_->interested_parties()); + pending_child_policy_.reset(); } - child_policy_.reset(); - pending_child_policy_.reset(); } void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { @@ -2061,11 +2121,13 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::UpdateState( } else if (num_connecting > 0) { entry_->parent_->channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, - UniquePtr(New(this->entry_->parent_))); + UniquePtr(New( + this->entry_->parent_->Ref(DEBUG_LOCATION, "QueuePicker")))); } else if (num_idle > 0) { entry_->parent_->channel_control_helper()->UpdateState( GRPC_CHANNEL_IDLE, - UniquePtr(New(this->entry_->parent_))); + UniquePtr(New( + this->entry_->parent_->Ref(DEBUG_LOCATION, "QueuePicker")))); } else { GPR_ASSERT(num_transient_failures == locality_map.size()); grpc_error* error = From 0054afef6e3985a7a6aba61204995b4799c00b20 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 10 Jun 2019 13:32:59 -0700 Subject: [PATCH 318/676] Fix usage of new and delete --- src/core/lib/iomgr/cfstream_handle.cc | 5 +++-- src/core/lib/iomgr/cfstream_handle.h | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 2fda160f68a..8d01386a8f9 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/port.h" #ifdef GRPC_CFSTREAM @@ -47,7 +48,7 @@ void CFStreamHandle::Release(void* info) { CFStreamHandle* CFStreamHandle::CreateStreamHandle( CFReadStreamRef read_stream, CFWriteStreamRef write_stream) { - return new CFStreamHandle(read_stream, write_stream); + return grpc_core::New(read_stream, write_stream); } void CFStreamHandle::ReadCallback(CFReadStreamRef stream, @@ -188,7 +189,7 @@ void CFStreamHandle::Unref(const char* file, int line, const char* reason) { reason, val, val - 1); } if (gpr_unref(&refcount_)) { - delete this; + grpc_core::Delete(this); } } diff --git a/src/core/lib/iomgr/cfstream_handle.h b/src/core/lib/iomgr/cfstream_handle.h index 4f4d15966e4..05f45ed6251 100644 --- a/src/core/lib/iomgr/cfstream_handle.h +++ b/src/core/lib/iomgr/cfstream_handle.h @@ -29,6 +29,7 @@ #ifdef GRPC_CFSTREAM #import +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/lockfree_event.h" @@ -65,6 +66,9 @@ class CFStreamHandle final { dispatch_queue_t dispatch_queue_; gpr_refcount refcount_; + + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE }; #ifdef DEBUG From 559023c01d74008b6029c3c3debd748665f630cb Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 12 Jun 2019 15:05:01 -0700 Subject: [PATCH 319/676] Adopt reviewer's advice --- examples/python/debug/README.md | 37 ++++++++++++++++++++++----- examples/python/debug/debug_server.py | 5 ++-- examples/python/debug/get_stats.py | 3 --- examples/python/debug/send_message.py | 3 --- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/examples/python/debug/README.md b/examples/python/debug/README.md index db57c79de84..ceed31ef767 100644 --- a/examples/python/debug/README.md +++ b/examples/python/debug/README.md @@ -1,13 +1,21 @@ # gRPC Python Debug Example -This example demonstrate the usage of Channelz. For a better looking website, the [gdebug](https://github.com/grpc/grpc-experiments/tree/master/gdebug) uses gRPC-Web protocol and will serve all useful information in web pages. +This example demonstrate the usage of Channelz. For a better looking website, +the [gdebug](https://github.com/grpc/grpc-experiments/tree/master/gdebug) uses +gRPC-Web protocol and will serve all useful information in web pages. ## Channelz: Live Channel Tracing -Channelz is a channel tracing feature. It will track statistics like how many messages have been sent, how many of them failed, what are the connected sockets. Since it is implemented in C-Core and has low-overhead, it is recommended to turn on for production services. See [Channelz design doc](https://github.com/grpc/proposal/blob/master/A14-channelz.md). +Channelz is a channel tracing feature. It will track statistics like how many +messages have been sent, how many of them failed, what are the connected +sockets. Since it is implemented in C-Core and has low-overhead, it is +recommended to turn on for production services. See [Channelz design +doc](https://github.com/grpc/proposal/blob/master/A14-channelz.md). ## How to enable tracing log -The tracing log generation might have larger overhead, especially when you try to trace transport. It would result in replicating the traffic loads. However, it is still the most powerful tool when you need to dive in. +The tracing log generation might have larger overhead, especially when you try +to trace transport. It would result in replicating the traffic loads. However, +it is still the most powerful tool when you need to dive in. ### The Most Verbose Tracing Log @@ -18,7 +26,8 @@ GRPC_VERBOSITY=debug GRPC_TRACE=all ``` -For more granularity, please see [environment_variables](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md). +For more granularity, please see +[environment_variables](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md). ### Debug Transport Protocol @@ -36,8 +45,24 @@ GRPC_TRACE=call_error,connectivity_state,pick_first,round_robin,glb ## How to debug your application? -`pdb` is a debugging tool that is available for Python interpreters natively. You can set breakpoint, and execute commands while the application is stopped. +`pdb` is a debugging tool that is available for Python interpreters natively. +You can set breakpoint, and execute commands while the application is stopped. -The simplest usage is add a single line in the place you want to inspect: `import pdb; pdb.set_trace()`. When interpreter see this line, it would pop out a interactive command line interface for you to inspect the application state. +The simplest usage is add a single line in the place you want to inspect: +`import pdb; pdb.set_trace()`. When interpreter see this line, it would pop out +a interactive command line interface for you to inspect the application state. For more detailed usage, see https://docs.python.org/3/library/pdb.html. + +**Caveat**: gRPC Python uses C-Extension under-the-hood, so `pdb` may not be +able to trace through the whole stack. + +## gRPC Command Line Tool + +`grpc_cli` is a handy tool to interact with gRPC backend easily. Imageine you can +inspect what service does a server provide without writing any code, and make +gRPC calls just like `curl`. + +The installation guide: https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md#code-location +The usage guide: https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md#usage +The source code: https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc diff --git a/examples/python/debug/debug_server.py b/examples/python/debug/debug_server.py index 2866d284267..64926b53457 100644 --- a/examples/python/debug/debug_server.py +++ b/examples/python/debug/debug_server.py @@ -45,12 +45,11 @@ class FaultInjectGreeter(helloworld_pb2_grpc.GreeterServicer): if random.random() < self._failure_rate: context.abort(grpc.StatusCode.UNAVAILABLE, 'Randomly injected failure.') - return helloworld_pb2.HelloReply( - message='Hello, %s!' % request.name) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def create_server(addr, failure_rate): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + server = grpc.server(futures.ThreadPoolExecutor()) helloworld_pb2_grpc.add_GreeterServicer_to_server( FaultInjectGreeter(failure_rate), server) diff --git a/examples/python/debug/get_stats.py b/examples/python/debug/get_stats.py index 22924098d51..d0b7061c54f 100644 --- a/examples/python/debug/get_stats.py +++ b/examples/python/debug/get_stats.py @@ -25,9 +25,6 @@ from grpc_channelz.v1 import channelz_pb2_grpc def run(addr): - # NOTE(gRPC Python Team): .close() is possible on a channel and should be - # used in circumstances in which the with statement does not fit the needs - # of the code. with grpc.insecure_channel(addr) as channel: channelz_stub = channelz_pb2_grpc.ChannelzStub(channel) response = channelz_stub.GetServers( diff --git a/examples/python/debug/send_message.py b/examples/python/debug/send_message.py index 99425263b50..3bad52c8fac 100644 --- a/examples/python/debug/send_message.py +++ b/examples/python/debug/send_message.py @@ -34,9 +34,6 @@ def process(stub, request): def run(addr, n): - # NOTE(gRPC Python Team): .close() is possible on a channel and should be - # used in circumstances in which the with statement does not fit the needs - # of the code. with grpc.insecure_channel(addr) as channel: stub = helloworld_pb2_grpc.GreeterStub(channel) request = helloworld_pb2.HelloRequest(name='you') From 4275312e5174149357283c263e10c45c5552dd4b Mon Sep 17 00:00:00 2001 From: John Luo Date: Thu, 13 Jun 2019 10:54:22 -0700 Subject: [PATCH 320/676] Mark as experiemental --- src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml index dd220bf564d..2728c8bfdc2 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml @@ -28,7 +28,7 @@ + Description="The base type to use for the client. This is an experimental feature."> From 94d41f031956357e142278ce34d773da1449e4f1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 13 Jun 2019 11:46:14 -0700 Subject: [PATCH 321/676] Simplify LB policy and resolver shutdown. --- .../filters/client_channel/client_channel.cc | 7 ++----- .../ext/filters/client_channel/lb_policy.cc | 19 ++----------------- .../ext/filters/client_channel/lb_policy.h | 4 +--- .../client_channel/lb_policy/xds/xds.cc | 3 +++ .../ext/filters/client_channel/resolver.h | 14 +++----------- 5 files changed, 11 insertions(+), 36 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a67792fcd37..40f8cef522b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1435,10 +1435,8 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) std::move(target_uri), ProcessResolverResultLocked, this, error)); grpc_channel_args_destroy(new_args); if (*error != GRPC_ERROR_NONE) { - // Orphan the resolving LB policy and flush the exec_ctx to ensure - // that it finishes shutting down. This ensures that if we are - // failing, we destroy the ClientChannelControlHelper (and thus - // unref the channel stack) before we return. + // Before we return, shut down the resolving LB policy, which destroys + // the ClientChannelControlHelper and therefore unrefs the channel stack. // TODO(roth): This is not a complete solution, because it only // catches the case where channel stack initialization fails in this // particular filter. If there is a failure in a different filter, we @@ -1446,7 +1444,6 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) // in practice, there are no other filters that can cause failures in // channel stack initialization, so this works for now. resolving_lb_policy_.reset(); - ExecCtx::Get()->Flush(); } else { grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), interested_parties_); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 3e4d3703c82..3207f888044 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -43,23 +43,8 @@ LoadBalancingPolicy::~LoadBalancingPolicy() { } void LoadBalancingPolicy::Orphan() { - // Invoke ShutdownAndUnrefLocked() inside of the combiner. - // TODO(roth): Is this actually needed? We should already be in the - // combiner here. Note that if we directly call ShutdownLocked(), - // then we can probably remove the hack whereby the helper is - // destroyed at shutdown instead of at destruction. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, - grpc_combiner_scheduler(combiner_)), - GRPC_ERROR_NONE); -} - -void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, - grpc_error* ignored) { - LoadBalancingPolicy* policy = static_cast(arg); - policy->ShutdownLocked(); - policy->channel_control_helper_.reset(); - policy->Unref(); + ShutdownLocked(); + Unref(); } // diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index c21e9d90ec4..ecc235bb71b 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -282,6 +282,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties() const { return interested_parties_; } + // Note: This must be invoked while holding the combiner. void Orphan() override; // A picker that returns PICK_QUEUE for all picks. @@ -322,7 +323,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { // Note: LB policies MUST NOT call any method on the helper from their // constructor. - // Note: This will return null after ShutdownLocked() has been called. ChannelControlHelper* channel_control_helper() const { return channel_control_helper_.get(); } @@ -331,8 +331,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void ShutdownLocked() GRPC_ABSTRACT; private: - static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored); - /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; /// Owned pointer to interested parties in load balancing decisions. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 74660cec92b..ca6ab216515 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1989,6 +1989,9 @@ void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { parent_->interested_parties()); pending_child_policy_.reset(); } + // Drop our ref to the child's picker, in case it's holding a ref to + // the child. + picker_ref_.reset(); } void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 87a4442d75b..829a860040a 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -117,12 +117,10 @@ class Resolver : public InternallyRefCounted { /// implementations. At that point, this method can go away. virtual void ResetBackoffLocked() {} + // Note: This must be invoked while holding the combiner. void Orphan() override { - // Invoke ShutdownAndUnrefLocked() inside of the combiner. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&Resolver::ShutdownAndUnrefLocked, this, - grpc_combiner_scheduler(combiner_)), - GRPC_ERROR_NONE); + ShutdownLocked(); + Unref(); } GRPC_ABSTRACT_BASE_CLASS @@ -147,12 +145,6 @@ class Resolver : public InternallyRefCounted { ResultHandler* result_handler() const { return result_handler_.get(); } private: - static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { - Resolver* resolver = static_cast(arg); - resolver->ShutdownLocked(); - resolver->Unref(); - } - UniquePtr result_handler_; grpc_combiner* combiner_; }; From c0d9289a7e4093f40ffb89a2c162cbfb56dcc5f1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 6 Jun 2019 10:25:37 -0700 Subject: [PATCH 322/676] Stop misspelling our own project name --- src/core/ext/filters/client_channel/resolver.h | 2 +- src/core/lib/channel/channelz_registry.h | 4 ++-- src/core/lib/gprpp/memory.h | 4 ++-- src/core/lib/gprpp/orphanable.h | 2 +- src/core/lib/gprpp/ref_counted.h | 6 +++--- src/core/lib/iomgr/buffer_list.h | 2 +- src/core/lib/slice/slice.cc | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 9aa504225ad..87a4442d75b 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -128,7 +128,7 @@ class Resolver : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE /// Does NOT take ownership of the reference to \a combiner. // TODO(roth): Once we have a C++-like interface for combiners, this diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index 73b330785d2..a0c431e091d 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -67,8 +67,8 @@ class ChannelzRegistry { static void LogAllEntities() { Default()->InternalLogAllEntities(); } private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE friend class testing::ChannelzRegistryPeer; ChannelzRegistry(); diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index b4b63ae771a..70ad430c51d 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -29,12 +29,12 @@ // Add this to a class that want to use Delete(), but has a private or // protected destructor. -#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ template \ friend void grpc_core::Delete(T*); // Add this to a class that want to use New(), but has a private or // protected constructor. -#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ template \ friend T* grpc_core::New(Args&&...); diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 2e467e49060..82350a19a2c 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -84,7 +84,7 @@ class InternallyRefCounted : public Orphanable { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE // Allow RefCountedPtr<> to access Unref() and IncrementRefCount(). template diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 83e9429ba37..3ef210e025f 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -44,7 +44,7 @@ class PolymorphicRefCount { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE virtual ~PolymorphicRefCount() = default; }; @@ -57,7 +57,7 @@ class NonPolymorphicRefCount { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE ~NonPolymorphicRefCount() = default; }; @@ -228,7 +228,7 @@ class RefCounted : public Impl { GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag. // Note: RefCount tracing is only enabled on debug builds, even when a diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 8bb271867c2..755ce02ba95 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -133,7 +133,7 @@ class TracedBuffer { grpc_error* shutdown_err); private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW TracedBuffer(uint32_t seq_no, void* arg) : seq_no_(seq_no), arg_(arg), next_(nullptr) {} diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 2bf2b0f499f..4a17188fdda 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -105,7 +105,7 @@ class NewSliceRefcount { user_destroy_(destroy), user_data_(user_data) {} - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE grpc_slice_refcount* base_refcount() { return &rc_; } @@ -154,7 +154,7 @@ class NewWithLenSliceRefcount { user_length_(user_length), user_destroy_(destroy) {} - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE grpc_slice_refcount* base_refcount() { return &rc_; } From 73180b1c0e2aa7304bdde1aecc3831c94db7cbe1 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 13 Jun 2019 13:59:52 -0700 Subject: [PATCH 323/676] Reduced instruction count for maybe_embiggen common case. --- src/core/lib/slice/slice_buffer.cc | 52 ++++++++++++++++++------------ 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index e1929250d4a..2b69f576a3c 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -32,35 +32,45 @@ /* grow a buffer; requires GRPC_SLICE_BUFFER_INLINE_ELEMENTS > 1 */ #define GROW(x) (3 * (x) / 2) +/* Typically, we do not actually need to embiggen (by calling + * memmove/malloc/realloc) - only if we were up against the full capacity of the + * slice buffer. If do_embiggen is inlined, the compiler clobbers multiple + * registers pointlessly in the common case. */ +static void GPR_ATTRIBUTE_NOINLINE do_embiggen(grpc_slice_buffer* sb, + const size_t slice_count, + const size_t slice_offset) { + if (slice_offset != 0) { + /* Make room by moving elements if there's still space unused */ + memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); + sb->slices = sb->base_slices; + } else { + /* Allocate more memory if no more space is available */ + const size_t new_capacity = GROW(sb->capacity); + sb->capacity = new_capacity; + if (sb->base_slices == sb->inlined) { + sb->base_slices = static_cast( + gpr_malloc(new_capacity * sizeof(grpc_slice))); + memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice)); + } else { + sb->base_slices = static_cast( + gpr_realloc(sb->base_slices, new_capacity * sizeof(grpc_slice))); + } + + sb->slices = sb->base_slices + slice_offset; + } +} + static void maybe_embiggen(grpc_slice_buffer* sb) { if (sb->count == 0) { sb->slices = sb->base_slices; + return; } /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = static_cast(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; - - if (slice_count == sb->capacity) { - if (sb->base_slices != sb->slices) { - /* Make room by moving elements if there's still space unused */ - memmove(sb->base_slices, sb->slices, sb->count * sizeof(grpc_slice)); - sb->slices = sb->base_slices; - } else { - /* Allocate more memory if no more space is available */ - sb->capacity = GROW(sb->capacity); - GPR_ASSERT(sb->capacity > slice_count); - if (sb->base_slices == sb->inlined) { - sb->base_slices = static_cast( - gpr_malloc(sb->capacity * sizeof(grpc_slice))); - memcpy(sb->base_slices, sb->inlined, slice_count * sizeof(grpc_slice)); - } else { - sb->base_slices = static_cast( - gpr_realloc(sb->base_slices, sb->capacity * sizeof(grpc_slice))); - } - - sb->slices = sb->base_slices + slice_offset; - } + if (GPR_UNLIKELY(slice_count == sb->capacity)) { + do_embiggen(sb, slice_count, slice_offset); } } From d8ddd592f94960226e588603eb31a361db6af8dc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Jun 2019 14:20:48 -0700 Subject: [PATCH 324/676] Rename cfg files and use opt configuration --- ...pc_buildtests_objc.cfg => grpc_basictests_objc_examples.cfg} | 2 +- .../{grpc_basictests_objc.cfg => grpc_basictests_objc_ios.cfg} | 2 +- .../{grpc_mactests_objc.cfg => grpc_basictests_objc_mac.cfg} | 2 +- ...pc_buildtests_objc.cfg => grpc_basictests_objc_examples.cfg} | 2 +- .../{grpc_basictests_objc.cfg => grpc_basictests_objc_ios.cfg} | 2 +- .../{grpc_mactests_objc.cfg => grpc_basictests_objc_mac.cfg} | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename tools/internal_ci/macos/{grpc_buildtests_objc.cfg => grpc_basictests_objc_examples.cfg} (94%) rename tools/internal_ci/macos/{grpc_basictests_objc.cfg => grpc_basictests_objc_ios.cfg} (94%) rename tools/internal_ci/macos/{grpc_mactests_objc.cfg => grpc_basictests_objc_mac.cfg} (94%) rename tools/internal_ci/macos/pull_request/{grpc_buildtests_objc.cfg => grpc_basictests_objc_examples.cfg} (94%) rename tools/internal_ci/macos/pull_request/{grpc_basictests_objc.cfg => grpc_basictests_objc_ios.cfg} (94%) rename tools/internal_ci/macos/pull_request/{grpc_mactests_objc.cfg => grpc_basictests_objc_mac.cfg} (94%) diff --git a/tools/internal_ci/macos/grpc_buildtests_objc.cfg b/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg similarity index 94% rename from tools/internal_ci/macos/grpc_buildtests_objc.cfg rename to tools/internal_ci/macos/grpc_basictests_objc_examples.cfg index d4bbcf5ab47..ccfc847cbef 100644 --- a/tools/internal_ci/macos/grpc_buildtests_objc.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-buildtest-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-buildtest-.*'" } diff --git a/tools/internal_ci/macos/grpc_basictests_objc.cfg b/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg similarity index 94% rename from tools/internal_ci/macos/grpc_basictests_objc.cfg rename to tools/internal_ci/macos/grpc_basictests_objc_ios.cfg index c5ee5015c3c..c6cf3e071d4 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-test-.*'" } diff --git a/tools/internal_ci/macos/grpc_mactests_objc.cfg b/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg similarity index 94% rename from tools/internal_ci/macos/grpc_mactests_objc.cfg rename to tools/internal_ci/macos/grpc_basictests_objc_mac.cfg index 2147e12eb85..fc7313e4b28 100644 --- a/tools/internal_ci/macos/grpc_mactests_objc.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r mac-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r mac-test-.*'" } diff --git a/tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg similarity index 94% rename from tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg rename to tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg index 8f35fda899a..a95c51c8c4a 100644 --- a/tools/internal_ci/macos/pull_request/grpc_buildtests_objc.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-buildtest-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-buildtest-.*'" } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg similarity index 94% rename from tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg rename to tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg index cb433413504..8b2fead4342 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-test-.*'" } diff --git a/tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg similarity index 94% rename from tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg rename to tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg index 5691375392e..43e3ca381ac 100644 --- a/tools/internal_ci/macos/pull_request/grpc_mactests_objc.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc dbg --internal_ci -j 1 --inner_jobs 4 --extra_args '-r mac-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r mac-test-.*'" } From 94a18020eb6652976e73d386f355cf0b08c28fc3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Jun 2019 16:11:17 -0700 Subject: [PATCH 325/676] nit fixes --- src/objective-c/GRPCClient/GRPCCall.m | 6 +++--- src/objective-c/tests/InteropTests/InteropTests.m | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 684867ae1ee..5280f8d01f4 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -161,12 +161,12 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSLog(@"Failed to create interceptor from factory: %@", globalInterceptorFactory); } else { [internalCall setResponseHandler:interceptor]; + nextInterceptor = interceptor; + nextManager = manager; } - nextInterceptor = interceptor; - nextManager = manager; } - // Finanlly initialize the interceptors in the chain + // Finally initialize the interceptors in the chain NSArray *interceptorFactories = _actualCallOptions.interceptorFactories; if (interceptorFactories.count == 0) { if (nextManager == nil) { diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index ef22a53cd96..6f00176b20c 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -1521,7 +1521,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - (void)testGlobalInterceptor { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = - [self expectationWithDescription:@"testLoggingInterceptor"]; + [self expectationWithDescription:@"testGlobalInterceptor"]; __block NSUInteger startCount = 0; __block NSUInteger writeDataCount = 0; From f08aab26bf132258a75e04266fd217196c5033d6 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 13 Jun 2019 16:11:51 -0700 Subject: [PATCH 326/676] Add test for 1 global interceptor and 1 local interceptor --- .../tests/InteropTests/InteropTests.m | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 6f00176b20c..962a15cbf8c 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -1666,4 +1666,174 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } +- (void)testIntecepptorAndGlobalInterceptor { + XCTAssertNotNil([[self class] host]); + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"testGlobalInterceptor"]; + + __block NSUInteger startCount = 0; + __block NSUInteger writeDataCount = 0; + __block NSUInteger finishCount = 0; + __block NSUInteger receiveNextMessageCount = 0; + __block NSUInteger responseHeaderCount = 0; + __block NSUInteger responseDataCount = 0; + __block NSUInteger responseCloseCount = 0; + __block NSUInteger didWriteDataCount = 0; + + id factory = [[HookInterceptorFactory alloc] + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + startCount++; + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] + callOptions:[callOptions copy]]; + } + writeDataHook:^(id data, GRPCInterceptorManager *manager) { + writeDataCount++; + [manager writeNextInterceptorWithData:data]; + } + finishHook:^(GRPCInterceptorManager *manager) { + finishCount++; + [manager finishNextInterceptor]; + } + receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { + receiveNextMessageCount++; + [manager receiveNextInterceptorMessages:numberOfMessages]; + } + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + responseHeaderCount++; + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(id data, GRPCInterceptorManager *manager) { + responseDataCount++; + [manager forwardPreviousInterceptorWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager) { + responseCloseCount++; + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; + } + didWriteDataHook:^(GRPCInterceptorManager *manager) { + didWriteDataCount++; + [manager forwardPreviousInterceptorDidWriteData]; + }]; + + __block NSUInteger globalStartCount = 0; + __block NSUInteger globalWriteDataCount = 0; + __block NSUInteger globalFinishCount = 0; + __block NSUInteger globalReceiveNextMessageCount = 0; + __block NSUInteger globalResponseHeaderCount = 0; + __block NSUInteger globalResponseDataCount = 0; + __block NSUInteger globalResponseCloseCount = 0; + __block NSUInteger globalDidWriteDataCount = 0; + + id globalFactory = [[HookInterceptorFactory alloc] + initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) + startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + globalStartCount++; + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] + callOptions:[callOptions copy]]; + } + writeDataHook:^(id data, GRPCInterceptorManager *manager) { + globalWriteDataCount++; + [manager writeNextInterceptorWithData:data]; + } + finishHook:^(GRPCInterceptorManager *manager) { + globalFinishCount++; + [manager finishNextInterceptor]; + } + receiveNextMessagesHook:^(NSUInteger numberOfMessages, GRPCInterceptorManager *manager) { + globalReceiveNextMessageCount++; + [manager receiveNextInterceptorMessages:numberOfMessages]; + } + responseHeaderHook:^(NSDictionary *initialMetadata, GRPCInterceptorManager *manager) { + globalResponseHeaderCount++; + [manager forwardPreviousInterceptorWithInitialMetadata:initialMetadata]; + } + responseDataHook:^(id data, GRPCInterceptorManager *manager) { + globalResponseDataCount++; + [manager forwardPreviousInterceptorWithData:data]; + } + responseCloseHook:^(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager) { + globalResponseCloseCount++; + [manager forwardPreviousInterceptorCloseWithTrailingMetadata:trailingMetadata error:error]; + } + didWriteDataHook:^(GRPCInterceptorManager *manager) { + globalDidWriteDataCount++; + [manager forwardPreviousInterceptorDidWriteData]; + }]; + + NSArray *requests = @[ @1, @2, @3, @4 ]; + NSArray *responses = @[ @1, @2, @3, @4 ]; + + __block int index = 0; + + id request = [RMTStreamingOutputCallRequest messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; + options.transportType = [[self class] transportType]; + options.PEMRootCertificates = [[self class] PEMRootCertificates]; + options.hostNameOverride = [[self class] hostNameOverride]; + options.flowControlEnabled = YES; + options.interceptorFactories = @[ factory ]; + [GRPCCall2 registerGlobalInterceptor:globalFactory]; + + __block BOOL canWriteData = NO; + __block GRPCStreamingProtoCall *call = [_service + fullDuplexCallWithResponseHandler:[[InteropTestsBlockCallbacks alloc] + initWithInitialMetadataCallback:nil + messageCallback:^(id message) { + index += 1; + if (index < 4) { + id request = [RMTStreamingOutputCallRequest + messageWithPayloadSize:requests[index] + requestedResponseSize:responses[index]]; + canWriteData = NO; + [call writeMessage:request]; + [call receiveNextMessage]; + } else { + [call finish]; + } + } + closeCallback:^(NSDictionary *trailingMetadata, + NSError *error) { + [expectation fulfill]; + } + writeMessageCallback:^{ + canWriteData = YES; + }] + callOptions:options]; + [call start]; + [call receiveNextMessage]; + [call writeMessage:request]; + + [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; + XCTAssertEqual(startCount, 1); + XCTAssertEqual(writeDataCount, 4); + XCTAssertEqual(finishCount, 1); + XCTAssertEqual(receiveNextMessageCount, 4); + XCTAssertEqual(responseHeaderCount, 1); + XCTAssertEqual(responseDataCount, 4); + XCTAssertEqual(responseCloseCount, 1); + XCTAssertEqual(didWriteDataCount, 4); + XCTAssertEqual(globalStartCount, 1); + XCTAssertEqual(globalWriteDataCount, 4); + XCTAssertEqual(globalFinishCount, 1); + XCTAssertEqual(globalReceiveNextMessageCount, 4); + XCTAssertEqual(globalResponseHeaderCount, 1); + XCTAssertEqual(globalResponseDataCount, 4); + XCTAssertEqual(globalResponseCloseCount, 1); + XCTAssertEqual(globalDidWriteDataCount, 4); +} + @end From cceca10a8a64e503a1cc21b6333736b400e75e1b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 13 Jun 2019 17:05:51 -0700 Subject: [PATCH 327/676] Fix data race, heap use-after-free issue in bm_chttp2_transport --- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 05504584c20..a82b10fc178 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -387,7 +387,7 @@ static void BM_TransportStreamSend(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; Fixture f(grpc::ChannelArguments(), true); - auto s = std::unique_ptr(new Stream(&f)); + auto* s = new Stream(&f); s->Init(state); grpc_transport_stream_op_batch op; grpc_transport_stream_op_batch_payload op_payload(nullptr); @@ -450,9 +450,8 @@ static void BM_TransportStreamSend(benchmark::State& state) { op.cancel_stream = true; op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; s->Op(&op); - s->DestroyThen(MakeOnceClosure([](grpc_error* error) {})); + s->DestroyThen(MakeOnceClosure([s](grpc_error* error) { delete s; })); f.FlushExecCtx(); - s.reset(); track_counters.Finish(state); grpc_metadata_batch_destroy(&b); grpc_slice_unref(send_slice); From a0f5cb45285bd9320c2c587c9a3b2fa7b2e7041c Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 13 Jun 2019 22:08:09 -0700 Subject: [PATCH 328/676] Fix assignment operator --- include/grpcpp/impl/codegen/call_op_set.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 95664a800fa..c3ae6c4e3d2 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -188,11 +188,6 @@ class WriteOptions { /// \sa GRPC_WRITE_LAST_MESSAGE bool is_last_message() const { return last_message_; } - WriteOptions& operator=(const WriteOptions& rhs) { - flags_ = rhs.flags_; - return *this; - } - private: void SetBit(const uint32_t mask) { flags_ |= mask; } From b216c3431469af4723cc10ea6712d3f7e8301c98 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 13 Jun 2019 22:15:53 -0700 Subject: [PATCH 329/676] Mark some methods virtual --- include/grpcpp/impl/codegen/server_callback.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index da08ec963e4..ab47873e40a 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -348,7 +348,8 @@ class ServerBidiReactor : public internal::ServerReactor { private: friend class ServerCallbackReaderWriter; - void BindStream(ServerCallbackReaderWriter* stream) { + virtual void BindStream( + ServerCallbackReaderWriter* stream) { stream_ = stream; } @@ -382,7 +383,9 @@ class ServerReadReactor : public internal::ServerReactor { private: friend class ServerCallbackReader; - void BindReader(ServerCallbackReader* reader) { reader_ = reader; } + virtual void BindReader(ServerCallbackReader* reader) { + reader_ = reader; + } ServerCallbackReader* reader_; }; @@ -424,7 +427,9 @@ class ServerWriteReactor : public internal::ServerReactor { private: friend class ServerCallbackWriter; - void BindWriter(ServerCallbackWriter* writer) { writer_ = writer; } + virtual void BindWriter(ServerCallbackWriter* writer) { + writer_ = writer; + } ServerCallbackWriter* writer_; }; From 46ed7524f90b1ddbf8fd005bb46dd7177ff7e6f7 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 14 Jun 2019 00:38:31 +0200 Subject: [PATCH 330/676] Bazel version syncup. --- templates/tools/dockerfile/bazel.include | 2 +- tools/dockerfile/test/bazel/Dockerfile | 2 +- tools/dockerfile/test/sanity/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index 272936007da..adde6ed4787 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -2,7 +2,7 @@ # Bazel installation # Must be in sync with tools/bazel -ENV BAZEL_VERSION 0.24.1 +ENV BAZEL_VERSION 0.26.0 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. ENV DISABLE_BAZEL_WRAPPER 1 diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index df7a7a2f32a..7e7903359e7 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -52,7 +52,7 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Bazel installation # Must be in sync with tools/bazel -ENV BAZEL_VERSION 0.24.1 +ENV BAZEL_VERSION 0.26.0 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. ENV DISABLE_BAZEL_WRAPPER 1 diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index 9a080d0efb2..ca786e264ed 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -98,7 +98,7 @@ ENV CLANG_TIDY=clang-tidy # Bazel installation # Must be in sync with tools/bazel -ENV BAZEL_VERSION 0.24.1 +ENV BAZEL_VERSION 0.26.0 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper. ENV DISABLE_BAZEL_WRAPPER 1 From a0dc6f7e4a94087e4a1c776cb68c0aa16cb1e47c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 14 Jun 2019 00:39:25 +0200 Subject: [PATCH 331/676] More syncup. --- tools/remote_build/rbe_common.bazelrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 63b49c5c42d..b494e173856 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -84,4 +84,4 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top -build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.23.0/ubsan:toolchain +build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.26.0/ubsan:toolchain From 0472933d71d82595d5796bbacce91d90f8ace280 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 14 Jun 2019 06:41:46 +0200 Subject: [PATCH 332/676] Trying to fix build. --- examples/python/multiprocessing/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 0e135f471f2..8140d80633a 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -36,7 +36,7 @@ py_binary( "//src/python/grpcio/grpc:grpcio", ":prime_proto_pb2", ], - default_python_version = "PY3", + python_version = "PY3", ) py_binary( @@ -50,7 +50,7 @@ py_binary( "//conditions:default": [requirement("futures")], "//:python3": [], }), - default_python_version = "PY3", + python_version = "PY3", ) py_test( From a3fd28bdbf9638c5a283b7586541b406c6663d51 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Jun 2019 02:33:01 -0400 Subject: [PATCH 333/676] fix ubsan build for 0.26 --- bazel/grpc_deps.bzl | 8 ++++---- tools/remote_build/rbe_common.bazelrc | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 4182a7157a0..eeb0546a973 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -186,11 +186,11 @@ def grpc_deps(): if "bazel_toolchains" not in native.existing_rules(): http_archive( name = "bazel_toolchains", - sha256 = "88e818f9f03628eef609c8429c210ecf265ffe46c2af095f36c7ef8b1855fef5", - strip_prefix = "bazel-toolchains-92dd8a7a518a2fb7ba992d47c8b38299fe0be825", + sha256 = "d968b414b32aa99c86977e1171645d31da2b52ac88060de3ac1e49932d5dcbf1", + strip_prefix = "bazel-toolchains-4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/4bd5df80d77aa7f4fb943dfdfad5c9056a62fb47.tar.gz", ], ) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index b494e173856..6baaf24732c 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -84,4 +84,7 @@ build:ubsan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:ubsan --test_timeout=3600 # override the config-agnostic crosstool_top -build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.26.0/ubsan:toolchain +# how to update the bazel toolchain for ubsan: +# - check for the latest released version in https://github.com/bazelbuild/bazel-toolchains/tree/master/configs/experimental/ubuntu16_04_clang +# - you might need to update the bazel_toolchains dependency in grpc_deps.bzl +build:ubsan --crosstool_top=@bazel_toolchains//configs/experimental/ubuntu16_04_clang/1.2/bazel_0.23.0/ubsan:toolchain From 19c9b193c560895292917415aac7ffe5333229f1 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 08:11:39 -0700 Subject: [PATCH 334/676] fix typos --- src/objective-c/tests/InteropTests/InteropTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 962a15cbf8c..2c54fb80f3d 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -1666,10 +1666,10 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager } } -- (void)testIntecepptorAndGlobalInterceptor { +- (void)testInterceptorAndGlobalInterceptor { XCTAssertNotNil([[self class] host]); __weak XCTestExpectation *expectation = - [self expectationWithDescription:@"testGlobalInterceptor"]; + [self expectationWithDescription:@"testInterceptorAndGlobalInterceptor"]; __block NSUInteger startCount = 0; __block NSUInteger writeDataCount = 0; From fce831a694056022275800bed5a9cc9a33b9f488 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 08:20:48 -0700 Subject: [PATCH 335/676] Add copyright and comment --- src/objective-c/tests/examples_build_test.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/objective-c/tests/examples_build_test.sh b/src/objective-c/tests/examples_build_test.sh index 7bf4d67d019..047106d8bd2 100755 --- a/src/objective-c/tests/examples_build_test.sh +++ b/src/objective-c/tests/examples_build_test.sh @@ -1,4 +1,19 @@ #!/bin/bash +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script is used after a release to verify the released pods are working appropriately set -ex From 5a354d79efbd284cf99f445175aea2b18f1b48c3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 10:16:19 -0700 Subject: [PATCH 336/676] fix cannot find tests --- tools/internal_ci/macos/grpc_basictests_objc_examples.cfg | 2 +- tools/internal_ci/macos/grpc_basictests_objc_ios.cfg | 2 +- tools/internal_ci/macos/grpc_basictests_objc_mac.cfg | 2 +- .../macos/pull_request/grpc_basictests_objc_examples.cfg | 2 +- .../macos/pull_request/grpc_basictests_objc_ios.cfg | 2 +- .../macos/pull_request/grpc_basictests_objc_mac.cfg | 2 +- tools/run_tests/run_tests_matrix.py | 5 +++-- 7 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg b/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg index ccfc847cbef..bdfd62c7937 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_examples.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-buildtest-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args -r ios-buildtest-.*" } diff --git a/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg b/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg index c6cf3e071d4..faef331cab5 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_ios.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r ios-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args -r ios-test-.*" } diff --git a/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg b/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg index fc7313e4b28..19849c357f3 100644 --- a/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg +++ b/tools/internal_ci/macos/grpc_basictests_objc_mac.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args '-r mac-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results --extra_args -r mac-test-.*" } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg index a95c51c8c4a..e2e55777ad1 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_examples.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-buildtest-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args -r ios-buildtest-.*" } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg index 8b2fead4342..4a4539b2353 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_ios.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r ios-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args -r ios-test-.*" } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg index 43e3ca381ac..98cf9345280 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_objc_mac.cfg @@ -27,5 +27,5 @@ action { env_vars { key: "RUN_TESTS_FLAGS" - value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args '-r mac-test-.*'" + value: "-f basictests macos objc opt --internal_ci -j 1 --inner_jobs 4 --extra_args -r mac-test-.*" } diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 7de1cb975d3..06a52b0f76e 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -246,7 +246,7 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): # supported on mac only. test_jobs += _generate_jobs( languages=['objc'], - configs=['dbg'], + configs=['opt'], platforms=['macos'], labels=['basictests', 'multilang'], extra_args=extra_args, @@ -523,6 +523,7 @@ if __name__ == "__main__": '--extra_args', default='', type=str, + nargs=argparse.REMAINDER, help='Extra test args passed to each sub-script.') args = argp.parse_args() @@ -542,7 +543,7 @@ if __name__ == "__main__": extra_args.append('%s' % args.bq_result_table) extra_args.append('--measure_cpu_costs') if args.extra_args: - extra_args.extend(('%s' % args.extra_args).split()) + extra_args.extend(args.extra_args) all_jobs = _create_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) + \ _create_portability_test_jobs(extra_args=extra_args, inner_jobs=args.inner_jobs) From 550dae1c4787531232c1b306dec12db22c7dfd88 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Jun 2019 10:41:35 -0700 Subject: [PATCH 337/676] Workaround the address contention issue --- .../python/debug/test/_debug_example_test.py | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/examples/python/debug/test/_debug_example_test.py b/examples/python/debug/test/_debug_example_test.py index 133fee2b0b6..af599e6a48b 100644 --- a/examples/python/debug/test/_debug_example_test.py +++ b/examples/python/debug/test/_debug_example_test.py @@ -32,30 +32,21 @@ _LOGGER.setLevel(logging.INFO) _FAILURE_RATE = 0.5 _NUMBER_OF_MESSAGES = 100 - -@contextmanager -def get_free_loopback_tcp_port(): - if socket.has_ipv6: - tcp_socket = socket.socket(socket.AF_INET6) - else: - tcp_socket = socket.socket(socket.AF_INET) - tcp_socket.bind(('', 0)) - address_tuple = tcp_socket.getsockname() - yield "localhost:%s" % (address_tuple[1]) - tcp_socket.close() - +_ADDR_TEMPLATE = 'localhost:%d' class DebugExampleTest(unittest.TestCase): def test_channelz_example(self): - with get_free_loopback_tcp_port() as addr: - server = debug_server.create_server( - addr=addr, failure_rate=_FAILURE_RATE) - server.start() - send_message.run(addr=addr, n=_NUMBER_OF_MESSAGES) - get_stats.run(addr=addr) - server.stop(None) - # No unhandled exception raised, test passed! + server = debug_server.create_server( + addr='[::]:0', failure_rate=_FAILURE_RATE) + port = server.add_insecure_port('[::]:0') + server.start() + address = _ADDR_TEMPLATE % port + + send_message.run(addr=address, n=_NUMBER_OF_MESSAGES) + get_stats.run(addr=address) + server.stop(None) + # No unhandled exception raised, test passed! if __name__ == '__main__': From 799ffbbd019ee48f8ecd96649c67850f9fc2595f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 12:25:45 -0700 Subject: [PATCH 338/676] Update license --- src/objective-c/tests/examples_build_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/examples_build_test.sh b/src/objective-c/tests/examples_build_test.sh index 047106d8bd2..92ebaacc82c 100755 --- a/src/objective-c/tests/examples_build_test.sh +++ b/src/objective-c/tests/examples_build_test.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2015 gRPC authors. +# Copyright 2019 gRPC authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 5b329fd1aa5a6a1ff4ae1d9b6c83e33342392c31 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 13:17:37 -0700 Subject: [PATCH 339/676] Add experimental notice to global interceptor --- src/objective-c/GRPCClient/GRPCCall+Interceptor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.h b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h index 953846d8c99..4183e0aa20e 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Interceptor.h +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h @@ -16,6 +16,8 @@ * */ +// The global interceptor feature is experimental and might be modified or removed at any time. + #import "GRPCCall.h" @protocol GRPCInterceptorFactory; From f05c475f010532c5dabc2d11b726cd00a5802736 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Jun 2019 14:34:37 -0700 Subject: [PATCH 340/676] Fix Python3 incompatibility --- test/core/bad_client/gen_build_yaml.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index bd311ccfd90..a4f3e4a0a34 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -17,6 +17,7 @@ """Generates the appropriate build.json data for all the bad_client tests.""" +from __future__ import print_function import collections import yaml @@ -77,7 +78,7 @@ def main(): ] } for t in sorted(BAD_CLIENT_TESTS.keys())]} - print yaml.dump(json) + print(yaml.dump(json)) if __name__ == '__main__': From 56a0153f167e1bf504e917fd527a08b67d6ace1e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 14 Jun 2019 14:44:49 -0700 Subject: [PATCH 341/676] Heap allocate the stream object for other benchmark cases too --- .../microbenchmarks/bm_chttp2_transport.cc | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index a82b10fc178..3df979e8ddb 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -259,18 +259,21 @@ static void BM_StreamCreateDestroy(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; Fixture f(grpc::ChannelArguments(), true); - Stream s(&f); + auto* s = new Stream(&f); grpc_transport_stream_op_batch op; grpc_transport_stream_op_batch_payload op_payload(nullptr); memset(&op, 0, sizeof(op)); op.cancel_stream = true; op.payload = &op_payload; op_payload.cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - std::unique_ptr next = MakeClosure([&](grpc_error* error) { - if (!state.KeepRunning()) return; - s.Init(state); - s.Op(&op); - s.DestroyThen(next.get()); + std::unique_ptr next = MakeClosure([&, s](grpc_error* error) { + if (!state.KeepRunning()) { + delete s; + return; + } + s->Init(state); + s->Op(&op); + s->DestroyThen(next.get()); }); GRPC_CLOSURE_RUN(next.get(), GRPC_ERROR_NONE); f.FlushExecCtx(); @@ -305,7 +308,7 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; Fixture f(grpc::ChannelArguments(), true); - Stream s(&f); + auto* s = new Stream(&f); grpc_transport_stream_op_batch op; grpc_transport_stream_op_batch_payload op_payload(nullptr); std::unique_ptr start; @@ -327,21 +330,24 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State& state) { } f.FlushExecCtx(); - start = MakeClosure([&](grpc_error* error) { - if (!state.KeepRunning()) return; - s.Init(state); + start = MakeClosure([&, s](grpc_error* error) { + if (!state.KeepRunning()) { + delete s; + return; + } + s->Init(state); reset_op(); op.on_complete = done.get(); op.send_initial_metadata = true; op.payload->send_initial_metadata.send_initial_metadata = &b; - s.Op(&op); + s->Op(&op); }); done = MakeClosure([&](grpc_error* error) { reset_op(); op.cancel_stream = true; op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - s.Op(&op); - s.DestroyThen(start.get()); + s->Op(&op); + s->DestroyThen(start.get()); }); GRPC_CLOSURE_SCHED(start.get(), GRPC_ERROR_NONE); f.FlushExecCtx(); @@ -355,8 +361,8 @@ static void BM_TransportEmptyOp(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; Fixture f(grpc::ChannelArguments(), true); - Stream s(&f); - s.Init(state); + auto* s = new Stream(&f); + s->Init(state); grpc_transport_stream_op_batch op; grpc_transport_stream_op_batch_payload op_payload(nullptr); auto reset_op = [&]() { @@ -367,15 +373,15 @@ static void BM_TransportEmptyOp(benchmark::State& state) { if (!state.KeepRunning()) return; reset_op(); op.on_complete = c.get(); - s.Op(&op); + s->Op(&op); }); GRPC_CLOSURE_SCHED(c.get(), GRPC_ERROR_NONE); f.FlushExecCtx(); reset_op(); op.cancel_stream = true; op_payload.cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - s.Op(&op); - s.DestroyThen(MakeOnceClosure([](grpc_error* error) {})); + s->Op(&op); + s->DestroyThen(MakeOnceClosure([s](grpc_error* error) { delete s; })); f.FlushExecCtx(); track_counters.Finish(state); } @@ -519,8 +525,8 @@ static void BM_TransportStreamRecv(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; Fixture f(grpc::ChannelArguments(), true); - Stream s(&f); - s.Init(state); + auto* s = new Stream(&f); + s->Init(state); grpc_transport_stream_op_batch_payload op_payload(nullptr); grpc_transport_stream_op_batch op; grpc_core::OrphanablePtr recv_stream; @@ -556,7 +562,7 @@ static void BM_TransportStreamRecv(benchmark::State& state) { std::unique_ptr c = MakeClosure([&](grpc_error* error) { if (!state.KeepRunning()) return; // force outgoing window to be yuge - s.chttp2_stream()->flow_control->TestOnlyForceHugeWindow(); + s->chttp2_stream()->flow_control->TestOnlyForceHugeWindow(); f.chttp2_transport()->flow_control->TestOnlyForceHugeWindow(); received = 0; reset_op(); @@ -564,7 +570,7 @@ static void BM_TransportStreamRecv(benchmark::State& state) { op.recv_message = true; op.payload->recv_message.recv_message = &recv_stream; op.payload->recv_message.recv_message_ready = drain_start.get(); - s.Op(&op); + s->Op(&op); f.PushInput(grpc_slice_ref(incoming_data)); }); @@ -605,7 +611,7 @@ static void BM_TransportStreamRecv(benchmark::State& state) { op.payload->recv_initial_metadata.recv_initial_metadata_ready = do_nothing.get(); op.on_complete = c.get(); - s.Op(&op); + s->Op(&op); f.PushInput(SLICE_FROM_BUFFER( "\x00\x00\x00\x04\x00\x00\x00\x00\x00" // Generated using: @@ -623,12 +629,12 @@ static void BM_TransportStreamRecv(benchmark::State& state) { reset_op(); op.cancel_stream = true; op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - s.Op(&op); - s.DestroyThen(MakeOnceClosure([](grpc_error* error) {})); - f.FlushExecCtx(); - track_counters.Finish(state); + s->Op(&op); + s->DestroyThen(MakeOnceClosure([s](grpc_error* error) { delete s; })); grpc_metadata_batch_destroy(&b); grpc_metadata_batch_destroy(&b_recv); + f.FlushExecCtx(); + track_counters.Finish(state); grpc_slice_unref(incoming_data); } BENCHMARK(BM_TransportStreamRecv)->Range(0, 128 * 1024 * 1024); From 0719ebd2ed3dd057d9630c26c013cdcd186cbede Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 14 Jun 2019 14:58:51 -0700 Subject: [PATCH 342/676] Use new connection for every test case --- src/objective-c/tests/InteropTests/InteropTests.m | 5 +++++ src/objective-c/tests/MacTests/StressTests.m | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 91e133a1300..197ab7f3da5 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -364,6 +364,11 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager [GRPCCall resetHostSettings]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [GRPCCall closeOpenConnections]; +#pragma clang diagnostic pop + _service = [[self class] host] ? [RMTTestService serviceWithHost:[[self class] host]] : nil; } diff --git a/src/objective-c/tests/MacTests/StressTests.m b/src/objective-c/tests/MacTests/StressTests.m index 22174b58665..3c6ecd52610 100644 --- a/src/objective-c/tests/MacTests/StressTests.m +++ b/src/objective-c/tests/MacTests/StressTests.m @@ -118,6 +118,11 @@ extern const char *kCFStreamVarName; [GRPCCall resetHostSettings]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [GRPCCall closeOpenConnections]; +#pragma clang diagnostic pop + GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = [[self class] transportType]; options.PEMRootCertificates = [[self class] PEMRootCertificates]; From 536765b2f3ca2f359c16e7353a2bcf21705e327e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Jun 2019 15:11:35 -0700 Subject: [PATCH 343/676] Surface exceptions in gevent IO manager --- .../grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi | 38 +++++++++---------- .../grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi | 30 +++++++-------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index 30fdf6a7600..dff6fa2aea5 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -67,25 +67,25 @@ cdef extern from "src/core/lib/iomgr/tcp_custom.h": ctypedef void (*grpc_custom_close_callback)(grpc_custom_socket* socket) struct grpc_socket_vtable: - grpc_error* (*init)(grpc_custom_socket* socket, int domain); + grpc_error* (*init)(grpc_custom_socket* socket, int domain) except * void (*connect)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, grpc_custom_connect_callback cb); - void (*destroy)(grpc_custom_socket* socket); - void (*shutdown)(grpc_custom_socket* socket); - void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb); + size_t len, grpc_custom_connect_callback cb) except * + void (*destroy)(grpc_custom_socket* socket) except * + void (*shutdown)(grpc_custom_socket* socket) except * + void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb) except * void (*write)(grpc_custom_socket* socket, grpc_slice_buffer* slices, - grpc_custom_write_callback cb); + grpc_custom_write_callback cb) except * void (*read)(grpc_custom_socket* socket, char* buffer, size_t length, - grpc_custom_read_callback cb); + grpc_custom_read_callback cb) except * grpc_error* (*getpeername)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len); + const grpc_sockaddr* addr, int* len) except * grpc_error* (*getsockname)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len); + const grpc_sockaddr* addr, int* len) except * grpc_error* (*bind)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags); - grpc_error* (*listen)(grpc_custom_socket* socket); + size_t len, int flags) except * + grpc_error* (*listen)(grpc_custom_socket* socket) except * void (*accept)(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb); + grpc_custom_accept_callback cb) except * cdef extern from "src/core/lib/iomgr/timer_custom.h": struct grpc_custom_timer: @@ -94,17 +94,17 @@ cdef extern from "src/core/lib/iomgr/timer_custom.h": # We don't care about the rest of the fields struct grpc_custom_timer_vtable: - void (*start)(grpc_custom_timer* t); - void (*stop)(grpc_custom_timer* t); + void (*start)(grpc_custom_timer* t) except * + void (*stop)(grpc_custom_timer* t) except * - void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error); + void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error) cdef extern from "src/core/lib/iomgr/pollset_custom.h": struct grpc_custom_poller_vtable: - void (*init)() - void (*poll)(size_t timeout_ms) - void (*kick)() - void (*shutdown)() + void (*init)() except * + void (*poll)(size_t timeout_ms) except * + void (*kick)() except * + void (*shutdown)() except * cdef extern from "src/core/lib/iomgr/iomgr_custom.h": void grpc_custom_iomgr_init(grpc_socket_vtable* socket, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index a1618d04d0e..3709cfb0296 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -84,7 +84,7 @@ cdef class SocketWrapper: self.c_buffer = NULL self.len = 0 -cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) with gil: +cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) except * with gil: sw = SocketWrapper() sw.c_socket = socket sw.sockopts = [] @@ -112,7 +112,7 @@ def socket_connect_async(socket_wrapper, addr_tuple): cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, size_t addr_len, - grpc_custom_connect_callback cb) with gil: + grpc_custom_connect_callback cb) except * with gil: py_socket = None socket_wrapper = socket.impl socket_wrapper.connect_cb = cb @@ -125,10 +125,10 @@ cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, socket_wrapper.socket = py_socket _spawn_greenlet(socket_connect_async, socket_wrapper, addr_tuple) -cdef void socket_destroy(grpc_custom_socket* socket) with gil: +cdef void socket_destroy(grpc_custom_socket* socket) except * with gil: cpython.Py_DECREF(socket.impl) -cdef void socket_shutdown(grpc_custom_socket* socket) with gil: +cdef void socket_shutdown(grpc_custom_socket* socket) except * with gil: try: (socket.impl).socket.shutdown(gevent_socket.SHUT_RDWR) except IOError as io_error: @@ -136,7 +136,7 @@ cdef void socket_shutdown(grpc_custom_socket* socket) with gil: raise io_error cdef void socket_close(grpc_custom_socket* socket, - grpc_custom_close_callback cb) with gil: + grpc_custom_close_callback cb) except * with gil: socket_wrapper = (socket.impl) if socket_wrapper.socket is not None: socket_wrapper.socket.close() @@ -176,7 +176,7 @@ def socket_write_async(socket_wrapper, write_bytes): socket_write_async_cython(socket_wrapper, write_bytes) cdef void socket_write(grpc_custom_socket* socket, grpc_slice_buffer* buffer, - grpc_custom_write_callback cb) with gil: + grpc_custom_write_callback cb) except * with gil: cdef char* start sw = socket.impl sw.write_cb = cb @@ -204,7 +204,7 @@ def socket_read_async(socket_wrapper): socket_read_async_cython(socket_wrapper) cdef void socket_read(grpc_custom_socket* socket, char* buffer, - size_t length, grpc_custom_read_callback cb) with gil: + size_t length, grpc_custom_read_callback cb) except * with gil: sw = socket.impl sw.read_cb = cb sw.c_buffer = buffer @@ -213,7 +213,7 @@ cdef void socket_read(grpc_custom_socket* socket, char* buffer, cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) with gil: + int* length) except * with gil: cdef char* src_buf peer = (socket.impl).socket.getpeername() @@ -226,7 +226,7 @@ cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, cdef grpc_error* socket_getsockname(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) with gil: + int* length) except * with gil: cdef char* src_buf cdef grpc_resolved_address c_addr if (socket.impl).socket is None: @@ -245,7 +245,7 @@ def applysockopts(s): cdef grpc_error* socket_bind(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags) with gil: + size_t len, int flags) except * with gil: addr_tuple = sockaddr_to_tuple(addr, len) try: try: @@ -262,7 +262,7 @@ cdef grpc_error* socket_bind(grpc_custom_socket* socket, else: return grpc_error_none() -cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil: +cdef grpc_error* socket_listen(grpc_custom_socket* socket) except * with gil: (socket.impl).socket.listen(50) return grpc_error_none() @@ -374,16 +374,16 @@ cdef void timer_stop(grpc_custom_timer* t) with gil: ### pollset implementation ### ############################### -cdef void init_loop() with gil: +cdef void init_loop() except * with gil: pass -cdef void destroy_loop() with gil: +cdef void destroy_loop() except * with gil: g_pool.join() -cdef void kick_loop() with gil: +cdef void kick_loop() except * with gil: g_event.set() -cdef void run_loop(size_t timeout_ms) with gil: +cdef void run_loop(size_t timeout_ms) except * with gil: timeout = timeout_ms / 1000.0 if timeout_ms > 0: g_event.wait(timeout) From 9df04d95a2227eb65ea65601f7d8b0eaa902c231 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 14 Jun 2019 15:52:36 -0700 Subject: [PATCH 344/676] merge upstream/master --- CMakeLists.txt | 41 ++++++++++++++++++ Makefile | 42 +++++++++++++++++++ .../generated/sources_and_headers.json | 19 +++++++++ tools/run_tests/generated/tests.json | 24 +++++++++++ 4 files changed, 126 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 900b527d9fa..c11643eca6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,6 +378,7 @@ add_dependencies(buildtests_c memory_usage_test) endif() add_dependencies(buildtests_c message_compress_test) add_dependencies(buildtests_c minimal_stack_is_minimal_test) +add_dependencies(buildtests_c mpmcqueue_test) add_dependencies(buildtests_c multiple_server_queues_test) add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) @@ -1083,6 +1084,7 @@ add_library(grpc src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -1518,6 +1520,7 @@ add_library(grpc_cronet src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -1935,6 +1938,7 @@ add_library(grpc_test_util src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -2265,6 +2269,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -2571,6 +2576,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -3597,6 +3603,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc + src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -9354,6 +9361,40 @@ target_link_libraries(minimal_stack_is_minimal_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(mpmcqueue_test + test/core/iomgr/mpmcqueue_test.cc +) + + +target_include_directories(mpmcqueue_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(mpmcqueue_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(mpmcqueue_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(mpmcqueue_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(multiple_server_queues_test test/core/end2end/multiple_server_queues_test.cc ) diff --git a/Makefile b/Makefile index 0325374e39e..9f05975da87 100644 --- a/Makefile +++ b/Makefile @@ -1092,6 +1092,7 @@ memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test +mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test @@ -1513,6 +1514,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/memory_usage_test \ $(BINDIR)/$(CONFIG)/message_compress_test \ $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \ + $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/multiple_server_queues_test \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ @@ -2092,6 +2094,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 ) $(E) "[RUN] Testing minimal_stack_is_minimal_test" $(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_test failed ; exit 1 ) + $(E) "[RUN] Testing mpmcqueue_test" + $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing multiple_server_queues_test" $(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 ) $(E) "[RUN] Testing murmur_hash_test" @@ -3561,6 +3565,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -3990,6 +3995,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4400,6 +4406,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4717,6 +4724,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4997,6 +5005,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -5996,6 +6005,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -12089,6 +12099,38 @@ endif endif +MPMCQUEUE_TEST_SRC = \ + test/core/iomgr/mpmcqueue_test.cc \ + +MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MPMCQUEUE_TEST_OBJS:.o=.dep) +endif +endif + + MULTIPLE_SERVER_QUEUES_TEST_SRC = \ test/core/end2end/multiple_server_queues_test.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0da1dc36ff9..12827875e32 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1626,6 +1626,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "mpmcqueue_test", + "src": [ + "test/core/iomgr/mpmcqueue_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8481,6 +8497,7 @@ "src/core/lib/iomgr/tcp_server_windows.cc", "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", + "src/core/lib/iomgr/threadpool/mpmcqueue.cc", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/timer.cc", "src/core/lib/iomgr/timer_custom.cc", @@ -8652,6 +8669,7 @@ "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", @@ -8809,6 +8827,7 @@ "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 473e2e26c3a..545d9c77233 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -1959,6 +1959,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "mpmcqueue_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From a633ad381416de7ba352c7a83e76d2619f40474a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 14 Jun 2019 15:54:59 -0700 Subject: [PATCH 345/676] add mpmcqueue implementation ad test --- BUILD | 2 + build.yaml | 11 + src/core/lib/iomgr/threadpool/mpmcqueue.cc | 143 ++++++++++++ src/core/lib/iomgr/threadpool/mpmcqueue.h | 148 ++++++++++++ test/core/iomgr/BUILD | 11 + test/core/iomgr/mpmcqueue_test.cc | 253 +++++++++++++++++++++ 6 files changed, 568 insertions(+) create mode 100644 src/core/lib/iomgr/threadpool/mpmcqueue.cc create mode 100644 src/core/lib/iomgr/threadpool/mpmcqueue.h create mode 100644 test/core/iomgr/mpmcqueue_test.cc diff --git a/BUILD b/BUILD index 29eed995008..10d0d650419 100644 --- a/BUILD +++ b/BUILD @@ -837,6 +837,7 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server_windows.cc", "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", + "src/core/lib/iomgr/threadpool/mpmcqueue.cc", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/timer.cc", "src/core/lib/iomgr/timer_custom.cc", @@ -982,6 +983,7 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/build.yaml b/build.yaml index bb53d6693fe..91d3cfe8c75 100644 --- a/build.yaml +++ b/build.yaml @@ -337,6 +337,7 @@ filegroups: - src/core/lib/iomgr/tcp_server_windows.cc - src/core/lib/iomgr/tcp_uv.cc - src/core/lib/iomgr/tcp_windows.cc + - src/core/lib/iomgr/threadpool/mpmcqueue.cc - src/core/lib/iomgr/time_averaged_stats.cc - src/core/lib/iomgr/timer.cc - src/core/lib/iomgr/timer_custom.cc @@ -507,6 +508,7 @@ filegroups: - src/core/lib/iomgr/tcp_server.h - src/core/lib/iomgr/tcp_server_utils_posix.h - src/core/lib/iomgr/tcp_windows.h + - src/core/lib/iomgr/threadpool/mpmcqueue.h - src/core/lib/iomgr/time_averaged_stats.h - src/core/lib/iomgr/timer.h - src/core/lib/iomgr/timer_custom.h @@ -3266,6 +3268,15 @@ targets: - grpc - gpr uses_polling: false +- name: mpmcqueue_test + build: test + language: c + src: + - test/core/iomgr/mpmcqueue_test.cc + deps: + - grpc_test_util + - grpc + - gpr - name: multiple_server_queues_test build: test language: c diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc new file mode 100644 index 00000000000..f33ab0468a8 --- /dev/null +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -0,0 +1,143 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" + +#include + +#include +#include +#include +#include +#include + +#include "src/core/lib/gprpp/sync.h" + +namespace grpc_core { + + + +inline void* MPMCQueue::PopFront() { + void* result = queue_head_->content; + Node* head_to_remove = queue_head_; + queue_head_ = queue_head_->next; + + count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED); + gpr_timespec wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), + head_to_remove->insert_time); + // gpr_free(head_to_remove); + delete head_to_remove; + + // Update Stats info + stats_.num_completed++; + stats_.total_queue_cycles = gpr_time_add(stats_.total_queue_cycles, + wait_time); + stats_.max_queue_cycles = gpr_time_max( + gpr_convert_clock_type(stats_.max_queue_cycles, GPR_TIMESPAN), wait_time); + + if (count_.Load(MemoryOrder::RELAXED) == 0) { + stats_.busy_time_cycles = gpr_time_add( + stats_.busy_time_cycles, + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); + } + + // Singal waiting thread + if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) { + wait_nonempty_.Signal(); + } + + return result; +} + +MPMCQueue::MPMCQueue() : num_waiters_(0), queue_head_(0), queue_tail_(0) { + count_.Store(0, MemoryOrder::RELAXED); +} + +MPMCQueue::~MPMCQueue() { + GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); + ReleasableMutexLock l(&mu_); + GPR_ASSERT(num_waiters_ == 0); + l.Unlock(); + PrintStats(); +} + +void MPMCQueue::Put(void* elem) { + MutexLock l(&mu_); + // Node* new_node = static_cast(gpr_malloc(sizeof(Node))); + // new_node->next = nullptr; + // new_node->content = elem; + // new_node->insert_time = gpr_now(GPR_CLOCK_PRECISE); + Node* new_node = static_cast(new Node(elem)); + if (count_.Load(MemoryOrder::RELAXED) == 0) { + busy_time = gpr_now(GPR_CLOCK_PRECISE); + queue_head_ = queue_tail_ = new_node; + } else { + queue_tail_->next = new_node; + queue_tail_ = queue_tail_->next; + } + count_.Store(count_.Load(MemoryOrder::RELAXED) + 1, MemoryOrder::RELAXED); + + // Update Stats info + stats_.num_started++; + + if (num_waiters_ > 0) { + wait_nonempty_.Signal(); + } +} + +void* MPMCQueue::Get() { + MutexLock l(&mu_); + if (count_.Load(MemoryOrder::RELAXED) == 0) { + num_waiters_++; + do { + wait_nonempty_.Wait(&mu_); + } while (count_.Load(MemoryOrder::RELAXED) == 0); + num_waiters_--; + } + GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); + return PopFront(); +} + +void MPMCQueue::PrintStats() { + MutexLock l(&mu_); + gpr_log(GPR_INFO, "STATS INFO:"); + gpr_log(GPR_INFO, "num_started: %lu", stats_.num_started); + gpr_log(GPR_INFO, "num_completed: %lu", stats_.num_completed); + gpr_log(GPR_INFO, "total_queue_cycles: %d", + gpr_time_to_millis(stats_.total_queue_cycles)); + gpr_log(GPR_INFO, "max_queue_cycles: %d", + gpr_time_to_millis(stats_.max_queue_cycles)); + gpr_log(GPR_INFO, "busy_time_cycles: %d", + gpr_time_to_millis(stats_.busy_time_cycles)); +} + +MPMCQueue::Stats* MPMCQueue::queue_stats() { + MPMCQueue::Stats* result = new Stats(); + MutexLock l(&mu_); + result->total_queue_cycles = gpr_time_add(result->total_queue_cycles, + stats_.total_queue_cycles); + result->max_queue_cycles = gpr_time_add(result->max_queue_cycles, + stats_.max_queue_cycles); + result->busy_time_cycles = gpr_time_add(result->busy_time_cycles, + stats_.busy_time_cycles); + return result; +} + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h new file mode 100644 index 00000000000..153784ae939 --- /dev/null +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -0,0 +1,148 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H +#define GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H + +#include + +#include +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/sync.h" +#include + +namespace grpc_core { + +// Abstract base class of a MPMC queue interface +class MPMCQueueInterface { + public: + MPMCQueueInterface() {} + virtual ~MPMCQueueInterface() {} + + // Put elem into queue immediately at the end of queue. + // This might cause to block on full queue depending on implementation. + virtual void Put(void *elem) = 0; + + // Remove the oldest element from the queue and return it. + // This might cause to block on empty queue depending on implementation. + virtual void* Get() = 0; + + // Return number of elements in the queue currently + virtual int count() const = 0; +}; + +class MPMCQueue : public MPMCQueueInterface { + public: + struct Stats { // Stats of queue + uint64_t num_started; // Number of elements have been added to queue + uint64_t num_completed; // Number of elements have been removed from + // the queue + gpr_timespec total_queue_cycles; // Total waiting time that all the + // removed elements have spent in queue + gpr_timespec max_queue_cycles; // Max waiting time among all removed + // elements + gpr_timespec busy_time_cycles; // Accumulated amount of time that queue + // was not empty + + Stats() { + num_started = 0; + num_completed = 0; + total_queue_cycles = gpr_time_0(GPR_TIMESPAN); + max_queue_cycles = gpr_time_0(GPR_TIMESPAN); + busy_time_cycles = gpr_time_0(GPR_TIMESPAN); + } + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } + }; + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } + // Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created + // will have infinite length. + explicit MPMCQueue(); + + // Release all resources hold by the queue. The queue must be empty, and no + // one waiting on conditional variables. + ~MPMCQueue(); + + // Put elem into queue immediately at the end of queue. Since the queue has + // infinite length, this routine will never block and should never fail. + void Put(void* elem); + + // Remove the oldest element from the queue and return it. + // This routine will cause the thread to block if queue is currently empty. + void* Get(); + + // Return number of elements in queue currently. + // There might be concurrently add/remove on queue, so count might change + // quickly. + int count() const { return count_.Load(MemoryOrder::RELAXED); } + + // Print out Stats. Time measurement are printed in millisecond. + void PrintStats(); + + // Return a copy of current stats info. This info will be changed quickly + // when queue is still running. This copy will not deleted by queue. + Stats* queue_stats(); + + private: + void* PopFront(); + + struct Node { + Node *next; // Linking + void *content; // Points to actual element + gpr_timespec insert_time; // Time for stats + Node(void* c) : content(c) { + next = nullptr; + insert_time = gpr_now(GPR_CLOCK_PRECISE); + } + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } + }; + + Mutex mu_; // Protecting lock + CondVar wait_nonempty_; // Wait on empty queue on get + int num_waiters_; // Number of waiters + + Node *queue_head_; // Head of the queue, remove position + Node *queue_tail_; // End of queue, insert position + Atomic count_; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H */ diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 1aefa0ab224..af67d5de25e 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -130,6 +130,17 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "mpmcqueue_test", + srcs = ["mpmcqueue_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "resolve_address_using_ares_resolver_posix_test", srcs = ["resolve_address_posix_test.cc"], diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc new file mode 100644 index 00000000000..d562f3c6722 --- /dev/null +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -0,0 +1,253 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" + +#include +#include +#include + +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/thd.h" +#include "test/core/util/test_config.h" + +#define THREAD_SMALL_ITERATION 100 +#define THREAD_LARGE_ITERATION 10000 + +static void test_no_op(void) { + gpr_log(GPR_DEBUG, "test_no_op"); + grpc_core::MPMCQueue mpmcqueue; + gpr_log(GPR_DEBUG, "Checking count..."); + GPR_ASSERT(mpmcqueue.count() == 0); + gpr_log(GPR_DEBUG, "Done."); +} + +// Testing items for queue +struct WorkItem { + int index; + bool done; + + WorkItem(int i) : index(i) { + done = false; + } + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } +}; + +static void test_small_queue(void) { + gpr_log(GPR_DEBUG, "test_small_queue"); + grpc_core::MPMCQueue small_queue; + for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + small_queue.Put(static_cast(new WorkItem(i))); + } + GPR_ASSERT(small_queue.count() == THREAD_SMALL_ITERATION); + // Get items out in FIFO order + for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + WorkItem* item = static_cast(small_queue.Get()); + GPR_ASSERT(i == item->index); + delete item; + } +} + +static void test_get_thd(void* args) { + grpc_core::MPMCQueue* mpmcqueue = static_cast(args); + + // count number of Get() called in this thread + int count = 0; + int last_index = -1; + WorkItem* item; + while ((item = static_cast(mpmcqueue->Get())) != NULL) { + count++; + GPR_ASSERT(item->index > last_index); + last_index = item->index; + GPR_ASSERT(!item->done); + delete item; + } + + gpr_log(GPR_DEBUG, "test_get_thd: %d times of Get() called.", count); +} + +static void test_get_empty(void) { + gpr_log(GPR_DEBUG, "test_get_empty"); + grpc_core::MPMCQueue mpmcqueue; + const int num_threads = 10; + grpc_core::Thread thds[num_threads]; + + // Fork threads. Threads should block at the beginning since queue is empty. + for (int i = 0; i < num_threads; ++i) { + thds[i] = grpc_core::Thread("mpmcq_test_ge_thd", test_get_thd, &mpmcqueue); + thds[i].Start(); + } + + for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + mpmcqueue.Put(static_cast(new WorkItem(i))); + } + + gpr_log(GPR_DEBUG, "Terminating threads..."); + for (int i = 0; i < num_threads; ++i) { + mpmcqueue.Put(NULL); + } + for (int i = 0; i < num_threads; ++i) { + thds[i].Join(); + } + gpr_log(GPR_DEBUG, "Done."); +} + +static void test_large_queue(void) { + gpr_log(GPR_DEBUG, "test_large_queue"); + grpc_core::MPMCQueue large_queue; + for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + large_queue.Put(static_cast(new WorkItem(i))); + } + GPR_ASSERT(large_queue.count() == THREAD_LARGE_ITERATION); + for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + WorkItem* item = static_cast(large_queue.Get()); + GPR_ASSERT(i == item->index); + delete item; + } +} + +// Thread for put items into queue +class WorkThread { + public: + WorkThread(grpc_core::MPMCQueue* mpmcqueue, int start_index, int num_items) + : start_index_(start_index), num_items_(num_items), + mpmcqueue_(mpmcqueue) { + items_ = NULL; + thd_ = grpc_core::Thread( + "mpmcq_test_mt_put_thd", + [](void* th) { static_cast(th)->Run(); }, + this); + } + ~WorkThread() { + for (int i = 0; i < num_items_; ++i) { + GPR_ASSERT(items_[i]->done); + delete items_[i]; + } + gpr_free(items_); + } + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } + + private: + void Run() { + items_ = static_cast( + gpr_malloc(sizeof(WorkItem*) * num_items_)); + for (int i = 0; i < num_items_; ++i) { + items_[i] = new WorkItem(start_index_ + i); + mpmcqueue_->Put(items_[i]); + } + } + + int start_index_; + int num_items_; + grpc_core::MPMCQueue* mpmcqueue_; + grpc_core::Thread thd_; + WorkItem** items_; +}; + + +static void test_many_get_thd(void* args) { + grpc_core::MPMCQueue* mpmcqueue = static_cast(args); + + // count number of Get() called in this thread + int count = 0; + + WorkItem* item; + while ((item = static_cast(mpmcqueue->Get())) != NULL) { + count++; + GPR_ASSERT(!item->done); + item->done = true; + } + + gpr_log(GPR_DEBUG, "test_many_get_thd: %d times of Get() called.", count); +} + +static void test_many_thread(void) { + gpr_log(GPR_DEBUG, "test_many_thread"); + const int num_work_thd = 10; + const int num_get_thd = 20; + grpc_core::MPMCQueue mpmcqueue; + WorkThread** work_thds = + static_cast(gpr_malloc(sizeof(WorkThread*) * num_work_thd)); + grpc_core::Thread get_thds[num_get_thd]; + + gpr_log(GPR_DEBUG, "Fork WorkThread..."); + for (int i = 0; i < num_work_thd; ++i) { + work_thds[i] = new WorkThread(&mpmcqueue, i * THREAD_LARGE_ITERATION, + THREAD_LARGE_ITERATION); + work_thds[i]->Start(); + } + gpr_log(GPR_DEBUG, "WorkThread Started."); + gpr_log(GPR_DEBUG, "For Getter Thread..."); + for (int i = 0; i < num_get_thd; ++i) { + get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", + test_many_get_thd, &mpmcqueue); + get_thds[i].Start(); + } + gpr_log(GPR_DEBUG, "Getter Thread Started."); + gpr_log(GPR_DEBUG, "Waiting WorkThread to finish..."); + for (int i = 0; i < num_work_thd; ++i) { + work_thds[i]->Join(); + } + gpr_log(GPR_DEBUG, "All WorkThread Terminated."); + gpr_log(GPR_DEBUG, "Terminating Getter Thread..."); + for (int i = 0; i < num_get_thd; ++i) { + mpmcqueue.Put(NULL); + } + for (int i = 0; i < num_get_thd; ++i) { + get_thds[i].Join(); + } + gpr_log(GPR_DEBUG, "All Getter Thread Terminated."); + gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); + for (int i = 0; i < num_work_thd; ++i) { + delete work_thds[i]; + } + gpr_free(work_thds); + gpr_log(GPR_DEBUG, "Done."); +} + + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + test_no_op(); + test_small_queue(); + test_get_empty(); + test_large_queue(); + test_many_thread(); + grpc_shutdown(); + return 0; +} From e60c43ff3ec55c67f99aa8dcece7eae8de177946 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 14 Jun 2019 16:13:19 -0700 Subject: [PATCH 346/676] Add out of bounds frame tests --- CMakeLists.txt | 41 +++++++ Makefile | 36 ++++++ test/core/bad_client/gen_build_yaml.py | 1 + test/core/bad_client/generate_tests.bzl | 1 + test/core/bad_client/tests/out_of_bounds.cc | 112 ++++++++++++++++++ .../generated/sources_and_headers.json | 17 +++ tools/run_tests/generated/tests.json | 26 ++++ 7 files changed, 234 insertions(+) create mode 100644 test/core/bad_client/tests/out_of_bounds.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d54ec0cda..276a1d64214 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -731,6 +731,7 @@ add_dependencies(buildtests_cxx head_of_line_blocking_bad_client_test) add_dependencies(buildtests_cxx headers_bad_client_test) add_dependencies(buildtests_cxx initial_settings_frame_bad_client_test) add_dependencies(buildtests_cxx large_metadata_bad_client_test) +add_dependencies(buildtests_cxx out_of_bounds_bad_client_test) add_dependencies(buildtests_cxx server_registered_method_bad_client_test) add_dependencies(buildtests_cxx simple_request_bad_client_test) add_dependencies(buildtests_cxx unknown_frame_bad_client_test) @@ -17307,6 +17308,46 @@ target_link_libraries(large_metadata_bad_client_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(out_of_bounds_bad_client_test + test/core/bad_client/tests/out_of_bounds.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(out_of_bounds_bad_client_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(out_of_bounds_bad_client_test + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + bad_client_test + grpc_test_util_unsecure + grpc_unsecure + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index d45c0992370..72c4f6854d2 100644 --- a/Makefile +++ b/Makefile @@ -1298,6 +1298,7 @@ head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test large_metadata_bad_client_test: $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test +out_of_bounds_bad_client_test: $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test @@ -1758,6 +1759,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \ $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ @@ -1917,6 +1919,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test \ + $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test \ $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \ $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \ @@ -2455,6 +2458,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing large_metadata_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/large_metadata_bad_client_test || ( echo test large_metadata_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing out_of_bounds_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test || ( echo test out_of_bounds_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing server_registered_method_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test || ( echo test server_registered_method_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing simple_request_bad_client_test" @@ -20540,6 +20545,37 @@ ifneq ($(NO_DEPS),true) endif +OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/out_of_bounds.cc \ + +OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_SRC)))) + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test: $(PROTOBUF_DEP) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/out_of_bounds_bad_client_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/out_of_bounds.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_out_of_bounds_bad_client_test: $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(OUT_OF_BOUNDS_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + SERVER_REGISTERED_METHOD_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/server_registered_method.cc \ diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index bd311ccfd90..aa5ae85cdf4 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -32,6 +32,7 @@ BAD_CLIENT_TESTS = { 'initial_settings_frame': default_test_options._replace(cpu_cost=0.2), 'head_of_line_blocking': default_test_options, 'large_metadata': default_test_options, + 'out_of_bounds': default_test_options, 'server_registered_method': default_test_options, 'simple_request': default_test_options, 'window_overflow': default_test_options, diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 9ff55877c53..81216f284cc 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -31,6 +31,7 @@ BAD_CLIENT_TESTS = { 'initial_settings_frame': test_options(), 'head_of_line_blocking': test_options(), 'large_metadata': test_options(), + 'out_of_bounds': test_options(), 'server_registered_method': test_options(), 'simple_request': test_options(), 'window_overflow': test_options(), diff --git a/test/core/bad_client/tests/out_of_bounds.cc b/test/core/bad_client/tests/out_of_bounds.cc new file mode 100644 index 00000000000..78d84a638a8 --- /dev/null +++ b/test/core/bad_client/tests/out_of_bounds.cc @@ -0,0 +1,112 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#include +#include "src/core/lib/surface/server.h" +#include "test/core/bad_client/bad_client.h" + +#define APPEND_BUFFER(string, to_append) \ + ((string).append((to_append), sizeof(to_append) - 1)) + +namespace { + +void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + while (grpc_server_has_open_connections(server)) { + GPR_ASSERT(grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(20), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + } +} + +void FrameVerifier(std::string attack_vector) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = nullptr; + args[1].client_payload = attack_vector.c_str(); + args[1].client_payload_length = attack_vector.size(); + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(OutOfBounds, MaxFrameSizeDataFrame) { + std::string out_of_bounds_data; + // Send a data frame larger than 2^14 + APPEND_BUFFER(out_of_bounds_data, "\x01\x00\x00\x00\x00\x00\x00\x00\x01"); + out_of_bounds_data.append(1 << 16, 'a'); + FrameVerifier(out_of_bounds_data); +} + +TEST(OutOfBounds, BadSizePriorityFrame) { + std::string bad_size_priority_frame; + // Priority Frame should be a length of 5 octets + APPEND_BUFFER(bad_size_priority_frame, + "\x00\x00\x03\x02\x00\x00\x00\x00\x01" + "\x11\x11\x12"); + FrameVerifier(bad_size_priority_frame); +} + +TEST(OutOfBounds, BadSizeRstStream) { + std::string bad_size_rst_stream; + // Rst Stream Frame should have a length of 4 octets + APPEND_BUFFER(bad_size_rst_stream, + "\x00\x00\x02\x03\x00\x00\x00\x00\x01" + "\x11\x11"); + FrameVerifier(bad_size_rst_stream); +} + +TEST(OutOfBounds, BadSizeSettings) { + std::string bad_size_settings; + // Settings Frame should have a length which is a multiple of 6 octets + APPEND_BUFFER(bad_size_settings, + "\x00\x00\x05\x04\x00\x00\x00\x00\x00" + "\x11\x11\x11\x11\x11"); + FrameVerifier(bad_size_settings); +} + +TEST(OutOfBounds, BadSizePing) { + std::string bad_size_ping; + // Rst Stream Frame should have a length of 8 octets + APPEND_BUFFER(bad_size_ping, + "\x00\x00\x05\x06\x00\x00\x00\x00\x00" + "\x11\x11\x11\x11\x11"); + FrameVerifier(bad_size_ping); +} + +TEST(OutOfBounds, WindowUpdate) { + std::string bad_size_window_update; + // Window Update Frame should have a length of 4 octets + APPEND_BUFFER(bad_size_window_update, + "\x00\x00\x01\x08\x00\x00\x00\x00\x00" + "\x11"); + FrameVerifier(bad_size_window_update); +} + +} // namespace + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); + grpc_shutdown(); + return retval; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3143f2cc87f..43fc3cc05ec 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5386,6 +5386,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "out_of_bounds_bad_client_test", + "src": [ + "test/core/bad_client/tests/out_of_bounds.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 37a69a47b23..5c24ec4fa15 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -6100,6 +6100,32 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "out_of_bounds_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 9f10ab5377589ebd6918c3c092b23f7aa8355e8d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 14 Jun 2019 16:24:12 -0700 Subject: [PATCH 347/676] Add gtest dependency to the test instead of library --- test/core/bad_client/generate_tests.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 9ff55877c53..da372dd0bc9 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -42,9 +42,6 @@ def grpc_bad_client_tests(): name = 'bad_client_test', srcs = ['bad_client.cc'], hdrs = ['bad_client.h'], - external_deps = [ - "gtest", - ], language = "C++", deps = ['//test/core/util:grpc_test_util', '//:grpc', '//:gpr', '//test/core/end2end:cq_verifier'] ) @@ -53,5 +50,8 @@ def grpc_bad_client_tests(): name = '%s_bad_client_test' % t, srcs = ['tests/%s.cc' % t], deps = [':bad_client_test'], + external_deps = [ + "gtest", + ], ) From 9bd526260a014237983246bc3af79c4fe4966474 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Jun 2019 16:49:53 -0700 Subject: [PATCH 348/676] Remove unused imports --- examples/python/debug/test/_debug_example_test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/python/debug/test/_debug_example_test.py b/examples/python/debug/test/_debug_example_test.py index af599e6a48b..8983542cb66 100644 --- a/examples/python/debug/test/_debug_example_test.py +++ b/examples/python/debug/test/_debug_example_test.py @@ -19,8 +19,6 @@ from __future__ import print_function import logging import unittest -from contextlib import contextmanager -import socket from examples.python.debug import debug_server from examples.python.debug import send_message @@ -34,6 +32,7 @@ _NUMBER_OF_MESSAGES = 100 _ADDR_TEMPLATE = 'localhost:%d' + class DebugExampleTest(unittest.TestCase): def test_channelz_example(self): From e0a95c3267eb608bd63c464a92513db3d252bb91 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 14 Jun 2019 16:53:14 -0700 Subject: [PATCH 349/676] Add more missing functions --- .../grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi | 6 +++--- .../grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index dff6fa2aea5..59b3891d9fa 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -44,12 +44,12 @@ cdef extern from "src/core/lib/iomgr/resolve_address_custom.h": pass struct grpc_custom_resolver_vtable: - grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res); - void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port); + grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res) except * + void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port) except * void grpc_custom_resolve_callback(grpc_custom_resolver* resolver, grpc_resolved_addresses* result, - grpc_error* error); + grpc_error* error) cdef extern from "src/core/lib/iomgr/tcp_custom.h": struct grpc_custom_socket: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index 3709cfb0296..f82fca2cce7 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -56,7 +56,7 @@ cdef sockaddr_is_ipv4(const grpc_sockaddr* address, size_t length): c_addr.len = length return grpc_sockaddr_get_uri_scheme(&c_addr) == b'ipv4' -cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups): +cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups) except *: cdef grpc_resolved_addresses* addresses tups_set = set((tup[4][0], tup[4][1]) for tup in tups) addresses = malloc(sizeof(grpc_resolved_addresses)) @@ -292,7 +292,7 @@ def socket_accept_async(s): accept_callback_cython(s) cdef void socket_accept(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb) with gil: + grpc_custom_accept_callback cb) except * with gil: sw = socket.impl sw.accepting_socket = client sw.accept_cb = cb @@ -322,7 +322,7 @@ cdef socket_resolve_async_cython(ResolveWrapper resolve_wrapper): def socket_resolve_async_python(resolve_wrapper): socket_resolve_async_cython(resolve_wrapper) -cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) with gil: +cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) except * with gil: rw = ResolveWrapper() rw.c_resolver = r rw.c_host = host @@ -330,7 +330,7 @@ cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) _spawn_greenlet(socket_resolve_async_python, rw) cdef grpc_error* socket_resolve(char* host, char* port, - grpc_resolved_addresses** res) with gil: + grpc_resolved_addresses** res) except * with gil: try: result = gevent_socket.getaddrinfo(host, port) res[0] = tuples_to_resolvaddr(result) @@ -360,13 +360,13 @@ cdef class TimerWrapper: self.event.set() self.timer.stop() -cdef void timer_start(grpc_custom_timer* t) with gil: +cdef void timer_start(grpc_custom_timer* t) except * with gil: timer = TimerWrapper(t.timeout_ms / 1000.0) timer.c_timer = t t.timer = timer timer.start() -cdef void timer_stop(grpc_custom_timer* t) with gil: +cdef void timer_stop(grpc_custom_timer* t) except * with gil: time_wrapper = t.timer time_wrapper.stop() From 85f08100d4b30c2ac1d655617d381688b8779169 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sun, 16 Jun 2019 16:01:46 -0400 Subject: [PATCH 350/676] Avoid using seq_cst atomic operations in grpcpp when unnecessary. These cases are almost all in the callback API. Also use atomic insteda of atomic_int for consistency with gpr_atm and grpc_core::Atomic. --- include/grpcpp/impl/codegen/client_callback.h | 51 +++++++++++-------- include/grpcpp/impl/codegen/server_callback.h | 42 ++++++++------- .../grpcpp/impl/codegen/server_interceptor.h | 10 ++-- include/grpcpp/server_impl.h | 2 +- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 6cba5830e4b..86d06b72c91 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H +#include #include #include @@ -419,7 +420,8 @@ class ClientCallbackReaderWriterImpl static void operator delete(void*, void*) { assert(0); } void MaybeFinish() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { Status s = std::move(finish_status_); auto* reactor = reactor_; auto* call = call_.call(); @@ -489,7 +491,7 @@ class ClientCallbackReaderWriterImpl void Read(Response* msg) override { read_ops_.RecvMessage(msg); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&read_ops_); } else { @@ -510,7 +512,7 @@ class ClientCallbackReaderWriterImpl } // TODO(vjpai): don't assert GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&write_ops_); } else { @@ -531,7 +533,7 @@ class ClientCallbackReaderWriterImpl }, &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&writes_done_ops_); } else { @@ -539,8 +541,10 @@ class ClientCallbackReaderWriterImpl } } - virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } - virtual void RemoveHold() override { MaybeFinish(); } + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } private: friend class ClientCallbackReaderWriterFactory; @@ -581,7 +585,7 @@ class ClientCallbackReaderWriterImpl bool read_ops_at_start_{false}; // Minimum of 2 callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + std::atomic callbacks_outstanding_{2}; bool started_{false}; }; @@ -619,7 +623,8 @@ class ClientCallbackReaderImpl static void operator delete(void*, void*) { assert(0); } void MaybeFinish() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { Status s = std::move(finish_status_); auto* reactor = reactor_; auto* call = call_.call(); @@ -669,7 +674,7 @@ class ClientCallbackReaderImpl void Read(Response* msg) override { read_ops_.RecvMessage(msg); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&read_ops_); } else { @@ -677,8 +682,10 @@ class ClientCallbackReaderImpl } } - virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } - virtual void RemoveHold() override { MaybeFinish(); } + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } private: friend class ClientCallbackReaderFactory; @@ -712,7 +719,7 @@ class ClientCallbackReaderImpl bool read_ops_at_start_{false}; // Minimum of 2 callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + std::atomic callbacks_outstanding_{2}; bool started_{false}; }; @@ -750,7 +757,8 @@ class ClientCallbackWriterImpl static void operator delete(void*, void*) { assert(0); } void MaybeFinish() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { Status s = std::move(finish_status_); auto* reactor = reactor_; auto* call = call_.call(); @@ -819,7 +827,7 @@ class ClientCallbackWriterImpl } // TODO(vjpai): don't assert GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&write_ops_); } else { @@ -840,7 +848,7 @@ class ClientCallbackWriterImpl }, &writes_done_ops_); writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (started_) { call_.PerformOps(&writes_done_ops_); } else { @@ -848,8 +856,10 @@ class ClientCallbackWriterImpl } } - virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } - virtual void RemoveHold() override { MaybeFinish(); } + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } private: friend class ClientCallbackWriterFactory; @@ -889,7 +899,7 @@ class ClientCallbackWriterImpl bool writes_done_ops_at_start_{false}; // Minimum of 2 callbacks to pre-register for start and finish - std::atomic_int callbacks_outstanding_{2}; + std::atomic callbacks_outstanding_{2}; bool started_{false}; }; @@ -951,7 +961,8 @@ class ClientCallbackUnaryImpl final } void MaybeFinish() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { Status s = std::move(finish_status_); auto* reactor = reactor_; auto* call = call_.call(); @@ -991,7 +1002,7 @@ class ClientCallbackUnaryImpl final Status finish_status_; // This call will have 2 callbacks: start and finish - std::atomic_int callbacks_outstanding_{2}; + std::atomic callbacks_outstanding_{2}; bool started_{false}; }; diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index ab47873e40a..b0a13917e56 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -68,13 +68,13 @@ class ServerReactor { // remain unmet. void MaybeCallOnCancel() { - if (on_cancel_conditions_remaining_.fetch_sub( - 1, std::memory_order_acq_rel) == 1) { + if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { OnCancel(); } } - std::atomic_int on_cancel_conditions_remaining_{2}; + std::atomic on_cancel_conditions_remaining_{2}; }; template @@ -568,7 +568,7 @@ class CallbackUnaryHandler : public MethodHandler { void SendInitialMetadata(std::function f) override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 // and if performance of this operation matters meta_tag_.Set(call_.call(), @@ -618,7 +618,8 @@ class CallbackUnaryHandler : public MethodHandler { ResponseType* response() { return allocator_state_->response(); } void MaybeDone() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); allocator_state_->Release(); @@ -640,7 +641,7 @@ class CallbackUnaryHandler : public MethodHandler { experimental::MessageHolder* const allocator_state_; std::function call_requester_; - std::atomic_int callbacks_outstanding_{ + std::atomic callbacks_outstanding_{ 2}; // reserve for Finish and CompletionOp }; }; @@ -712,7 +713,7 @@ class CallbackClientStreamingHandler : public MethodHandler { void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); meta_tag_.Set(call_.call(), [this](bool ok) { reactor_->OnSendInitialMetadataDone(ok); @@ -730,7 +731,7 @@ class CallbackClientStreamingHandler : public MethodHandler { } void Read(RequestType* req) override { - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); read_ops_.RecvMessage(req); call_.PerformOps(&read_ops_); } @@ -761,7 +762,8 @@ class CallbackClientStreamingHandler : public MethodHandler { ResponseType* response() { return &resp_; } void MaybeDone() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { reactor_->OnDone(); grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); @@ -785,7 +787,7 @@ class CallbackClientStreamingHandler : public MethodHandler { ResponseType resp_; std::function call_requester_; experimental::ServerReadReactor* reactor_; - std::atomic_int callbacks_outstanding_{ + std::atomic callbacks_outstanding_{ 3}; // reserve for OnStarted, Finish, and CompletionOp }; }; @@ -867,7 +869,7 @@ class CallbackServerStreamingHandler : public MethodHandler { void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); meta_tag_.Set(call_.call(), [this](bool ok) { reactor_->OnSendInitialMetadataDone(ok); @@ -885,7 +887,7 @@ class CallbackServerStreamingHandler : public MethodHandler { } void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (options.is_last_message()) { options.set_buffer_hint(); } @@ -939,7 +941,8 @@ class CallbackServerStreamingHandler : public MethodHandler { const RequestType* request() { return req_; } void MaybeDone() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { reactor_->OnDone(); grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); @@ -963,7 +966,7 @@ class CallbackServerStreamingHandler : public MethodHandler { const RequestType* req_; std::function call_requester_; experimental::ServerWriteReactor* reactor_; - std::atomic_int callbacks_outstanding_{ + std::atomic callbacks_outstanding_{ 3}; // reserve for OnStarted, Finish, and CompletionOp }; }; @@ -1031,7 +1034,7 @@ class CallbackBidiHandler : public MethodHandler { void SendInitialMetadata() override { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); meta_tag_.Set(call_.call(), [this](bool ok) { reactor_->OnSendInitialMetadataDone(ok); @@ -1049,7 +1052,7 @@ class CallbackBidiHandler : public MethodHandler { } void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); if (options.is_last_message()) { options.set_buffer_hint(); } @@ -1077,7 +1080,7 @@ class CallbackBidiHandler : public MethodHandler { } void Read(RequestType* req) override { - callbacks_outstanding_++; + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); read_ops_.RecvMessage(req); call_.PerformOps(&read_ops_); } @@ -1112,7 +1115,8 @@ class CallbackBidiHandler : public MethodHandler { ~ServerCallbackReaderWriterImpl() {} void MaybeDone() { - if (--callbacks_outstanding_ == 0) { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { reactor_->OnDone(); grpc_call* call = call_.call(); auto call_requester = std::move(call_requester_); @@ -1137,7 +1141,7 @@ class CallbackBidiHandler : public MethodHandler { Call call_; std::function call_requester_; experimental::ServerBidiReactor* reactor_; - std::atomic_int callbacks_outstanding_{ + std::atomic callbacks_outstanding_{ 3}; // reserve for OnStarted, Finish, and CompletionOp }; }; diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 28fdc27ec68..dc1da1327af 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -98,9 +98,7 @@ class ServerRpcInfo { ServerRpcInfo(grpc_impl::ServerContext* ctx, const char* method, internal::RpcMethod::RpcType type) - : ctx_(ctx), method_(method), type_(static_cast(type)) { - ref_.store(1); - } + : ctx_(ctx), method_(method), type_(static_cast(type)) {} // Runs interceptor at pos \a pos. void RunInterceptor( @@ -122,9 +120,9 @@ class ServerRpcInfo { } } - void Ref() { ref_++; } + void Ref() { ref_.fetch_add(1, std::memory_order_relaxed); } void Unref() { - if (--ref_ == 0) { + if (GPR_UNLIKELY(ref_.fetch_sub(1, std::memory_order_acq_rel) == 1)) { delete this; } } @@ -132,7 +130,7 @@ class ServerRpcInfo { grpc_impl::ServerContext* ctx_ = nullptr; const char* method_ = nullptr; const Type type_; - std::atomic_int ref_; + std::atomic ref_{1}; std::vector> interceptors_; friend class internal::InterceptorBatchMethodsImpl; diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 90019e25032..b75012e5da8 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -342,7 +342,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { // during decreasing load, so it is less performance-critical. grpc::internal::Mutex callback_reqs_mu_; grpc::internal::CondVar callback_reqs_done_cv_; - std::atomic_int callback_reqs_outstanding_{0}; + std::atomic callback_reqs_outstanding_{0}; std::shared_ptr global_callbacks_; From 7db36fe0a0944d0157c0126ad0ca6036538483b9 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Jun 2019 11:18:03 -0700 Subject: [PATCH 351/676] Add comments and rename internal methods --- include/grpcpp/impl/codegen/server_callback.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index ab47873e40a..6d83bc88e56 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -174,7 +174,7 @@ class ServerCallbackReader { protected: template void BindReactor(ServerReadReactor* reactor) { - reactor->BindReader(this); + reactor->InternalBindReader(this); } }; @@ -196,7 +196,7 @@ class ServerCallbackWriter { protected: template void BindReactor(ServerWriteReactor* reactor) { - reactor->BindWriter(this); + reactor->InternalBindWriter(this); } }; @@ -218,7 +218,7 @@ class ServerCallbackReaderWriter { protected: void BindReactor(ServerBidiReactor* reactor) { - reactor->BindStream(this); + reactor->InternalBindStream(this); } }; @@ -348,7 +348,9 @@ class ServerBidiReactor : public internal::ServerReactor { private: friend class ServerCallbackReaderWriter; - virtual void BindStream( + // May be overridden by internal implementation details, this is not a public + // customization point. + virtual void InternalBindStream( ServerCallbackReaderWriter* stream) { stream_ = stream; } @@ -383,7 +385,9 @@ class ServerReadReactor : public internal::ServerReactor { private: friend class ServerCallbackReader; - virtual void BindReader(ServerCallbackReader* reader) { + // May be overridden by internal implementation details, this is not a public + // customization point. + virtual void InternalBindReader(ServerCallbackReader* reader) { reader_ = reader; } @@ -427,7 +431,9 @@ class ServerWriteReactor : public internal::ServerReactor { private: friend class ServerCallbackWriter; - virtual void BindWriter(ServerCallbackWriter* writer) { + // May be overridden by internal implementation details, this is not a public + // customization point. + virtual void InternalBindWriter(ServerCallbackWriter* writer) { writer_ = writer; } From 929f1510164238b36394aa6710a0e506b77344ff Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 17 Jun 2019 22:42:08 +0200 Subject: [PATCH 352/676] Cherry-picking #19349 in. --- examples/python/multiprocessing/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 8140d80633a..f9fa6598068 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -36,7 +36,7 @@ py_binary( "//src/python/grpcio/grpc:grpcio", ":prime_proto_pb2", ], - python_version = "PY3", + srcs_version = "PY3", ) py_binary( @@ -50,7 +50,7 @@ py_binary( "//conditions:default": [requirement("futures")], "//:python3": [], }), - python_version = "PY3", + srcs_version = "PY3", ) py_test( From 6fc7d2b18f51a2a9d1069d2e1c168d76b810fd44 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 14:47:28 -0700 Subject: [PATCH 353/676] fix undefined reference to operator delete for MPMCQueue interface class --- build.yaml | 20 +++--- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 44 ++++++------ src/core/lib/iomgr/threadpool/mpmcqueue.h | 78 ++++++++-------------- test/core/iomgr/mpmcqueue_test.cc | 43 +++--------- 4 files changed, 67 insertions(+), 118 deletions(-) diff --git a/build.yaml b/build.yaml index 91d3cfe8c75..a02d7f01fcb 100644 --- a/build.yaml +++ b/build.yaml @@ -3268,15 +3268,6 @@ targets: - grpc - gpr uses_polling: false -- name: mpmcqueue_test - build: test - language: c - src: - - test/core/iomgr/mpmcqueue_test.cc - deps: - - grpc_test_util - - grpc - - gpr - name: multiple_server_queues_test build: test language: c @@ -5239,6 +5230,17 @@ targets: - grpc++ - grpc - gpr +- name: mpmcqueue_test + build: test + language: c++ + src: + - test/core/iomgr/mpmcqueue_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: nonblocking_test gtest: true build: test diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index f33ab0468a8..e641ba70faa 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -16,46 +16,42 @@ * */ -#include - #include "src/core/lib/iomgr/threadpool/mpmcqueue.h" -#include - #include #include #include +#include #include #include +#include #include "src/core/lib/gprpp/sync.h" namespace grpc_core { - - inline void* MPMCQueue::PopFront() { void* result = queue_head_->content; Node* head_to_remove = queue_head_; queue_head_ = queue_head_->next; count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED); - gpr_timespec wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), - head_to_remove->insert_time); - // gpr_free(head_to_remove); + gpr_timespec wait_time = + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); + delete head_to_remove; // Update Stats info stats_.num_completed++; - stats_.total_queue_cycles = gpr_time_add(stats_.total_queue_cycles, - wait_time); + stats_.total_queue_cycles = + gpr_time_add(stats_.total_queue_cycles, wait_time); stats_.max_queue_cycles = gpr_time_max( gpr_convert_clock_type(stats_.max_queue_cycles, GPR_TIMESPAN), wait_time); if (count_.Load(MemoryOrder::RELAXED) == 0) { - stats_.busy_time_cycles = gpr_time_add( - stats_.busy_time_cycles, - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); + stats_.busy_time_cycles = + gpr_time_add(stats_.busy_time_cycles, + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); } // Singal waiting thread @@ -66,7 +62,8 @@ inline void* MPMCQueue::PopFront() { return result; } -MPMCQueue::MPMCQueue() : num_waiters_(0), queue_head_(0), queue_tail_(0) { +MPMCQueue::MPMCQueue() : num_waiters_(0), queue_head_(nullptr), + queue_tail_(nullptr) { count_.Store(0, MemoryOrder::RELAXED); } @@ -80,10 +77,7 @@ MPMCQueue::~MPMCQueue() { void MPMCQueue::Put(void* elem) { MutexLock l(&mu_); - // Node* new_node = static_cast(gpr_malloc(sizeof(Node))); - // new_node->next = nullptr; - // new_node->content = elem; - // new_node->insert_time = gpr_now(GPR_CLOCK_PRECISE); + Node* new_node = static_cast(new Node(elem)); if (count_.Load(MemoryOrder::RELAXED) == 0) { busy_time = gpr_now(GPR_CLOCK_PRECISE); @@ -131,12 +125,12 @@ void MPMCQueue::PrintStats() { MPMCQueue::Stats* MPMCQueue::queue_stats() { MPMCQueue::Stats* result = new Stats(); MutexLock l(&mu_); - result->total_queue_cycles = gpr_time_add(result->total_queue_cycles, - stats_.total_queue_cycles); - result->max_queue_cycles = gpr_time_add(result->max_queue_cycles, - stats_.max_queue_cycles); - result->busy_time_cycles = gpr_time_add(result->busy_time_cycles, - stats_.busy_time_cycles); + result->total_queue_cycles = + gpr_time_add(result->total_queue_cycles, stats_.total_queue_cycles); + result->max_queue_cycles = + gpr_time_add(result->max_queue_cycles, stats_.max_queue_cycles); + result->busy_time_cycles = + gpr_time_add(result->busy_time_cycles, stats_.busy_time_cycles); return result; } diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h index 153784ae939..18d30e876ab 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -16,15 +16,15 @@ * */ -#ifndef GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H -#define GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H +#ifndef GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H +#define GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H +#include #include +#include -#include #include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/sync.h" -#include namespace grpc_core { @@ -36,7 +36,7 @@ class MPMCQueueInterface { // Put elem into queue immediately at the end of queue. // This might cause to block on full queue depending on implementation. - virtual void Put(void *elem) = 0; + virtual void Put(void* elem) = 0; // Remove the oldest element from the queue and return it. // This might cause to block on empty queue depending on implementation. @@ -48,16 +48,16 @@ class MPMCQueueInterface { class MPMCQueue : public MPMCQueueInterface { public: - struct Stats { // Stats of queue - uint64_t num_started; // Number of elements have been added to queue - uint64_t num_completed; // Number of elements have been removed from - // the queue - gpr_timespec total_queue_cycles; // Total waiting time that all the - // removed elements have spent in queue - gpr_timespec max_queue_cycles; // Max waiting time among all removed - // elements - gpr_timespec busy_time_cycles; // Accumulated amount of time that queue - // was not empty + struct Stats { // Stats of queue + uint64_t num_started; // Number of elements have been added to queue + uint64_t num_completed; // Number of elements have been removed from + // the queue + gpr_timespec total_queue_cycles; // Total waiting time that all the + // removed elements have spent in queue + gpr_timespec max_queue_cycles; // Max waiting time among all removed + // elements + gpr_timespec busy_time_cycles; // Accumulated amount of time that queue + // was not empty Stats() { num_started = 0; @@ -66,23 +66,7 @@ class MPMCQueue : public MPMCQueueInterface { max_queue_cycles = gpr_time_0(GPR_TIMESPAN); busy_time_cycles = gpr_time_0(GPR_TIMESPAN); } - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } }; - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } // Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created // will have infinite length. explicit MPMCQueue(); @@ -115,34 +99,26 @@ class MPMCQueue : public MPMCQueueInterface { void* PopFront(); struct Node { - Node *next; // Linking - void *content; // Points to actual element - gpr_timespec insert_time; // Time for stats + Node* next; // Linking + void* content; // Points to actual element + gpr_timespec insert_time; // Time for stats Node(void* c) : content(c) { next = nullptr; insert_time = gpr_now(GPR_CLOCK_PRECISE); } - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } }; - Mutex mu_; // Protecting lock - CondVar wait_nonempty_; // Wait on empty queue on get - int num_waiters_; // Number of waiters + Mutex mu_; // Protecting lock + CondVar wait_nonempty_; // Wait on empty queue on get + int num_waiters_; // Number of waiters - Node *queue_head_; // Head of the queue, remove position - Node *queue_tail_; // End of queue, insert position - Atomic count_; // Number of elements in queue - Stats stats_; // Stats info - gpr_timespec busy_time; // Start time of busy queue + Node* queue_head_; // Head of the queue, remove position + Node* queue_tail_; // End of queue, insert position + Atomic count_; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core -#endif /* GRPC_CORE_LIB_IOMGR_MPMCQUEUE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H */ diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index d562f3c6722..60d06d30d77 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -42,17 +42,7 @@ struct WorkItem { int index; bool done; - WorkItem(int i) : index(i) { - done = false; - } - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } + WorkItem(int i) : index(i) { done = false; } }; static void test_small_queue(void) { @@ -132,38 +122,28 @@ static void test_large_queue(void) { class WorkThread { public: WorkThread(grpc_core::MPMCQueue* mpmcqueue, int start_index, int num_items) - : start_index_(start_index), num_items_(num_items), + : start_index_(start_index), + num_items_(num_items), mpmcqueue_(mpmcqueue) { items_ = NULL; thd_ = grpc_core::Thread( "mpmcq_test_mt_put_thd", - [](void* th) { static_cast(th)->Run(); }, - this); + [](void* th) { static_cast(th)->Run(); }, this); } ~WorkThread() { for (int i = 0; i < num_items_; ++i) { GPR_ASSERT(items_[i]->done); delete items_[i]; } - gpr_free(items_); + delete[] items_; } void Start() { thd_.Start(); } void Join() { thd_.Join(); } - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } - private: void Run() { - items_ = static_cast( - gpr_malloc(sizeof(WorkItem*) * num_items_)); + items_ = new WorkItem*[num_items_]; for (int i = 0; i < num_items_; ++i) { items_[i] = new WorkItem(start_index_ + i); mpmcqueue_->Put(items_[i]); @@ -177,7 +157,6 @@ class WorkThread { WorkItem** items_; }; - static void test_many_get_thd(void* args) { grpc_core::MPMCQueue* mpmcqueue = static_cast(args); @@ -199,8 +178,7 @@ static void test_many_thread(void) { const int num_work_thd = 10; const int num_get_thd = 20; grpc_core::MPMCQueue mpmcqueue; - WorkThread** work_thds = - static_cast(gpr_malloc(sizeof(WorkThread*) * num_work_thd)); + WorkThread** work_thds = new WorkThread*[num_work_thd]; grpc_core::Thread get_thds[num_get_thd]; gpr_log(GPR_DEBUG, "Fork WorkThread..."); @@ -212,8 +190,8 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "WorkThread Started."); gpr_log(GPR_DEBUG, "For Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", - test_many_get_thd, &mpmcqueue); + get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", test_many_get_thd, + &mpmcqueue); get_thds[i].Start(); } gpr_log(GPR_DEBUG, "Getter Thread Started."); @@ -234,11 +212,10 @@ static void test_many_thread(void) { for (int i = 0; i < num_work_thd; ++i) { delete work_thds[i]; } - gpr_free(work_thds); + delete[] work_thds; gpr_log(GPR_DEBUG, "Done."); } - int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); From 8c8dc0e3c70594507818d7fd6525ca5e276cd49b Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Mon, 17 Jun 2019 15:01:28 -0700 Subject: [PATCH 354/676] 1.21.4 interop for cxx, csharp, php, ruby and python --- tools/interop_matrix/client_matrix.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 43002c3b222..05c495f5633 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -97,6 +97,7 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), ('v1.19.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), ('v1.20.0', ReleaseInfo()), + ('v1.21.4', ReleaseInfo()), ]), 'go': OrderedDict( @@ -209,6 +210,7 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo()), ('v1.19.0', ReleaseInfo()), ('v1.20.0', ReleaseInfo()), + ('v1.21.4', ReleaseInfo()), ]), 'node': OrderedDict([ @@ -257,6 +259,7 @@ LANG_RELEASE_MATRIX = { ])), ('v1.19.0', ReleaseInfo()), ('v1.20.0', ReleaseInfo()), + ('v1.21.4', ReleaseInfo()), # TODO: https://github.com/grpc/grpc/issues/18262. # If you are not encountering the error in above issue # go ahead and upload the docker image for new releases. @@ -281,6 +284,7 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.18.0', ReleaseInfo()), + ('v1.21.4', ReleaseInfo()), # TODO:https://github.com/grpc/grpc/issues/18264 # Error in above issues needs to be resolved. ]), @@ -312,5 +316,6 @@ LANG_RELEASE_MATRIX = { ('v1.18.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), ('v1.20.0', ReleaseInfo()), + ('v1.21.4', ReleaseInfo()), ]), } From c2db456e16baa39088ede51ff406c9862a023f4c Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 15:03:23 -0700 Subject: [PATCH 355/676] Modify MPMCQueueInterface class defination for c++ compiler --- src/core/lib/iomgr/threadpool/mpmcqueue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h index 18d30e876ab..2aa5ec1cdaa 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -31,7 +31,6 @@ namespace grpc_core { // Abstract base class of a MPMC queue interface class MPMCQueueInterface { public: - MPMCQueueInterface() {} virtual ~MPMCQueueInterface() {} // Put elem into queue immediately at the end of queue. @@ -102,6 +101,7 @@ class MPMCQueue : public MPMCQueueInterface { Node* next; // Linking void* content; // Points to actual element gpr_timespec insert_time; // Time for stats + Node(void* c) : content(c) { next = nullptr; insert_time = gpr_now(GPR_CLOCK_PRECISE); From ee6a462f03094d21b69ff69426062f99526f6743 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 18 Jun 2019 00:23:56 +0200 Subject: [PATCH 356/676] Another python fix. --- tools/bazel.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bazel.rc b/tools/bazel.rc index 99347495361..6378b82017e 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -59,5 +59,5 @@ build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC build:python3 --python_path=python3 -build:python3 --force_python=PY3 +build:python3 --python_version=PY3 build:python3 --action_env=PYTHON_BIN_PATH=python3 From 0a1b6d8304070e7dc0a940e31ab2a7f5a91d2f84 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 15:33:35 -0700 Subject: [PATCH 357/676] Modify format - nullptr --- test/core/iomgr/mpmcqueue_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 60d06d30d77..e40a350c18c 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -67,7 +67,7 @@ static void test_get_thd(void* args) { int count = 0; int last_index = -1; WorkItem* item; - while ((item = static_cast(mpmcqueue->Get())) != NULL) { + while ((item = static_cast(mpmcqueue->Get())) != nullptr) { count++; GPR_ASSERT(item->index > last_index); last_index = item->index; @@ -96,7 +96,7 @@ static void test_get_empty(void) { gpr_log(GPR_DEBUG, "Terminating threads..."); for (int i = 0; i < num_threads; ++i) { - mpmcqueue.Put(NULL); + mpmcqueue.Put(nullptr); } for (int i = 0; i < num_threads; ++i) { thds[i].Join(); @@ -125,7 +125,7 @@ class WorkThread { : start_index_(start_index), num_items_(num_items), mpmcqueue_(mpmcqueue) { - items_ = NULL; + items_ = nullptr; thd_ = grpc_core::Thread( "mpmcq_test_mt_put_thd", [](void* th) { static_cast(th)->Run(); }, this); @@ -164,7 +164,7 @@ static void test_many_get_thd(void* args) { int count = 0; WorkItem* item; - while ((item = static_cast(mpmcqueue->Get())) != NULL) { + while ((item = static_cast(mpmcqueue->Get())) != nullptr) { count++; GPR_ASSERT(!item->done); item->done = true; @@ -202,7 +202,7 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "All WorkThread Terminated."); gpr_log(GPR_DEBUG, "Terminating Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - mpmcqueue.Put(NULL); + mpmcqueue.Put(nullptr); } for (int i = 0; i < num_get_thd; ++i) { get_thds[i].Join(); From 559afb59b2cecbba74ddd51b0cc9b7f0b68e3fd8 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 15:53:31 -0700 Subject: [PATCH 358/676] Re-format indentation --- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index e641ba70faa..a66cd91e92d 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -62,8 +62,8 @@ inline void* MPMCQueue::PopFront() { return result; } -MPMCQueue::MPMCQueue() : num_waiters_(0), queue_head_(nullptr), - queue_tail_(nullptr) { +MPMCQueue::MPMCQueue() + : num_waiters_(0), queue_head_(nullptr), queue_tail_(nullptr) { count_.Store(0, MemoryOrder::RELAXED); } From 7866e41a97aa8e11cefb1f20041cda52dc93fa5a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 16:17:40 -0700 Subject: [PATCH 359/676] Adjust include headers --- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 3 ++- src/core/lib/iomgr/threadpool/mpmcqueue.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index a66cd91e92d..b2e09b9c81b 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -16,12 +16,13 @@ * */ +#include + #include "src/core/lib/iomgr/threadpool/mpmcqueue.h" #include #include #include -#include #include #include #include diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h index 2aa5ec1cdaa..8c8395e1d9d 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -19,8 +19,9 @@ #ifndef GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H #define GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H -#include #include + +#include #include #include "src/core/lib/gprpp/atomic.h" From 4fc02c6bf546fd85076c9cd555eb91f4d04408bd Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Jun 2019 16:30:06 -0700 Subject: [PATCH 360/676] add tests for bad stream IDs --- CMakeLists.txt | 41 ++++++ Makefile | 36 +++++ test/core/bad_client/gen_build_yaml.py | 1 + test/core/bad_client/generate_tests.bzl | 1 + .../core/bad_client/tests/bad_streaming_id.cc | 132 ++++++++++++++++++ .../generated/sources_and_headers.json | 17 +++ tools/run_tests/generated/tests.json | 26 ++++ 7 files changed, 254 insertions(+) create mode 100644 test/core/bad_client/tests/bad_streaming_id.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d54ec0cda..f0b4dd562f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -724,6 +724,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx writes_per_rpc_test) endif() add_dependencies(buildtests_cxx xds_end2end_test) +add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test) add_dependencies(buildtests_cxx badreq_bad_client_test) add_dependencies(buildtests_cxx connection_prefix_bad_client_test) add_dependencies(buildtests_cxx duplicate_header_bad_client_test) @@ -17030,6 +17031,46 @@ target_link_libraries(gen_percent_encoding_tables if (gRPC_BUILD_TESTS) +add_executable(bad_streaming_id_bad_client_test + test/core/bad_client/tests/bad_streaming_id.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bad_streaming_id_bad_client_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bad_streaming_id_bad_client_test + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + bad_client_test + grpc_test_util_unsecure + grpc_unsecure + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(badreq_bad_client_test test/core/bad_client/tests/badreq.cc third_party/googletest/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index d45c0992370..4d04ba0e4be 100644 --- a/Makefile +++ b/Makefile @@ -1291,6 +1291,7 @@ gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test +bad_streaming_id_bad_client_test: $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test @@ -1751,6 +1752,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \ $(BINDIR)/$(CONFIG)/boringssl_crypto_test \ + $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ @@ -1910,6 +1912,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ + $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ @@ -2441,6 +2444,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) $(E) "[RUN] Testing xds_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing bad_streaming_id_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test || ( echo test bad_streaming_id_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing connection_prefix_bad_client_test" @@ -20323,6 +20328,37 @@ ifneq ($(NO_DEPS),true) endif +BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/bad_streaming_id.cc \ + +BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_STREAMING_ID_BAD_CLIENT_TEST_SRC)))) + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test: $(PROTOBUF_DEP) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/bad_streaming_id.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_bad_streaming_id_bad_client_test: $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(BAD_STREAMING_ID_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + BADREQ_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/badreq.cc \ diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index a4f3e4a0a34..d0ac94ae349 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -27,6 +27,7 @@ default_test_options = TestOptions(False, 1.0) # maps test names to options BAD_CLIENT_TESTS = { 'badreq': default_test_options, + 'bad_streaming_id': default_test_options, 'connection_prefix': default_test_options._replace(cpu_cost=0.2), 'duplicate_header': default_test_options, 'headers': default_test_options._replace(cpu_cost=0.2), diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index da372dd0bc9..5c9e688b82a 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -25,6 +25,7 @@ def test_options(): # maps test names to options BAD_CLIENT_TESTS = { 'badreq': test_options(), + 'bad_streaming_id': test_options(), 'connection_prefix': test_options(), 'duplicate_header': test_options(), 'headers': test_options(), diff --git a/test/core/bad_client/tests/bad_streaming_id.cc b/test/core/bad_client/tests/bad_streaming_id.cc new file mode 100644 index 00000000000..287db433880 --- /dev/null +++ b/test/core/bad_client/tests/bad_streaming_id.cc @@ -0,0 +1,132 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#include +#include "src/core/lib/surface/server.h" +#include "test/core/bad_client/bad_client.h" + +#define HEADER_FRAME_ID_1 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x01" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define HEADER_FRAME_ID_2 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x02" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define HEADER_FRAME_ID_3 \ + "\x00\x00\xc9\x01\x05\x00\x00\x00\x03" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +namespace { + +void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + while (grpc_server_has_open_connections(server)) { + GPR_ASSERT(grpc_completion_queue_next( + cq, grpc_timeout_milliseconds_to_deadline(20), nullptr) + .type == GRPC_QUEUE_TIMEOUT); + } +} + +TEST(BadStreamingId, RegularHeader) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_1; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(BadStreamingId, NonClientStreamId) { + grpc_bad_client_arg args[2]; + args[0] = connection_preface_arg; + // send a header frame with non-client stream id 2 + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_2; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_2) - 1; + grpc_run_bad_client_test(verifier, args, 2, GRPC_BAD_CLIENT_DISCONNECT); +} + +TEST(BadStreamingId, ClosedStreamId) { + grpc_bad_client_arg args[4]; + args[0] = connection_preface_arg; + // send a header frame with stream id 1 + args[1].client_validator = nullptr; + args[1].client_payload = HEADER_FRAME_ID_1; + args[1].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + // send a header frame with stream id 3 + args[2].client_validator = nullptr; + args[2].client_payload = HEADER_FRAME_ID_3; + args[2].client_payload_length = sizeof(HEADER_FRAME_ID_3) - 1; + // send a header frame with closed stream id 1 again + args[3].client_validator = nullptr; + args[3].client_payload = HEADER_FRAME_ID_1; + args[3].client_payload_length = sizeof(HEADER_FRAME_ID_1) - 1; + grpc_run_bad_client_test(verifier, args, 4, GRPC_BAD_CLIENT_DISCONNECT); +} + +} // namespace + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + int retval = RUN_ALL_TESTS(); + grpc_shutdown(); + return retval; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3143f2cc87f..6f59fab77af 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5267,6 +5267,23 @@ "third_party": true, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bad_streaming_id_bad_client_test", + "src": [ + "test/core/bad_client/tests/bad_streaming_id.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 37a69a47b23..43067e3620d 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5918,6 +5918,32 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bad_streaming_id_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 8a310e50637987902341ed9f9247c9ff443c1f9d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Jun 2019 16:48:30 -0700 Subject: [PATCH 361/676] Clang tidy --- test/core/bad_client/tests/out_of_bounds.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/bad_client/tests/out_of_bounds.cc b/test/core/bad_client/tests/out_of_bounds.cc index 78d84a638a8..b716e952bc1 100644 --- a/test/core/bad_client/tests/out_of_bounds.cc +++ b/test/core/bad_client/tests/out_of_bounds.cc @@ -38,7 +38,7 @@ void verifier(grpc_server* server, grpc_completion_queue* cq, } } -void FrameVerifier(std::string attack_vector) { +void FrameVerifier(const std::string& attack_vector) { grpc_bad_client_arg args[2]; args[0] = connection_preface_arg; args[1].client_validator = nullptr; From 70c8211c85946e2b665198e5cca05b2ed9275c97 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 16:57:30 -0700 Subject: [PATCH 362/676] Add config files --- config.m4 | 2 ++ config.w32 | 2 ++ gRPC-C++.podspec | 2 ++ gRPC-Core.podspec | 3 +++ grpc.gemspec | 2 ++ grpc.gyp | 4 ++++ package.xml | 2 ++ tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 2 ++ 9 files changed, 20 insertions(+) diff --git a/config.m4 b/config.m4 index bb30be56910..6782f94a2b2 100644 --- a/config.m4 +++ b/config.m4 @@ -184,6 +184,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ + src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -726,6 +727,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gprpp) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr/threadpool) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context) diff --git a/config.w32 b/config.w32 index c9faa8d9ac8..8bff737f51f 100644 --- a/config.w32 +++ b/config.w32 @@ -159,6 +159,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\tcp_server_windows.cc " + "src\\core\\lib\\iomgr\\tcp_uv.cc " + "src\\core\\lib\\iomgr\\tcp_windows.cc " + + "src\\core\\lib\\iomgr\\threadpool\\mpmcqueue.cc " + "src\\core\\lib\\iomgr\\time_averaged_stats.cc " + "src\\core\\lib\\iomgr\\timer.cc " + "src\\core\\lib\\iomgr\\timer_custom.cc " + @@ -739,6 +740,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gprpp"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr\\threadpool"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 18ed5f89102..55e7e9340a1 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -507,6 +507,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', @@ -711,6 +712,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 85add8fb7a2..56b3d5b0955 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -477,6 +477,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', @@ -646,6 +647,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -1130,6 +1132,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', + 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', diff --git a/grpc.gemspec b/grpc.gemspec index e9d215bf10f..0e21836c8d5 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -411,6 +411,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/tcp_server.h ) s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix.h ) s.files += %w( src/core/lib/iomgr/tcp_windows.h ) + s.files += %w( src/core/lib/iomgr/threadpool/mpmcqueue.h ) s.files += %w( src/core/lib/iomgr/time_averaged_stats.h ) s.files += %w( src/core/lib/iomgr/timer.h ) s.files += %w( src/core/lib/iomgr/timer_custom.h ) @@ -580,6 +581,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/tcp_server_windows.cc ) s.files += %w( src/core/lib/iomgr/tcp_uv.cc ) s.files += %w( src/core/lib/iomgr/tcp_windows.cc ) + s.files += %w( src/core/lib/iomgr/threadpool/mpmcqueue.cc ) s.files += %w( src/core/lib/iomgr/time_averaged_stats.cc ) s.files += %w( src/core/lib/iomgr/timer.cc ) s.files += %w( src/core/lib/iomgr/timer_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index 6268bed7bb0..f64c80c2008 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -366,6 +366,7 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -742,6 +743,7 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -992,6 +994,7 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -1218,6 +1221,7 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', diff --git a/package.xml b/package.xml index fd712698a62..77162f3d366 100644 --- a/package.xml +++ b/package.xml @@ -416,6 +416,7 @@ + @@ -585,6 +586,7 @@ + diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 9b0f8f9fcd7..e5e78ffbb4b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1172,6 +1172,7 @@ src/core/lib/iomgr/tcp_posix.h \ src/core/lib/iomgr/tcp_server.h \ src/core/lib/iomgr/tcp_server_utils_posix.h \ src/core/lib/iomgr/tcp_windows.h \ +src/core/lib/iomgr/threadpool/mpmcqueue.h \ src/core/lib/iomgr/time_averaged_stats.h \ src/core/lib/iomgr/timer.h \ src/core/lib/iomgr/timer_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7768bca30f5..83a9315d5af 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1331,6 +1331,8 @@ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ src/core/lib/iomgr/tcp_windows.h \ +src/core/lib/iomgr/threadpool/mpmcqueue.cc \ +src/core/lib/iomgr/threadpool/mpmcqueue.h \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/time_averaged_stats.h \ src/core/lib/iomgr/timer.cc \ From 62b53012361d5516c148260532bb8982fe074fdb Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 17 Jun 2019 17:01:17 -0700 Subject: [PATCH 363/676] Revert "Simplify LB policy and resolver shutdown." --- .../filters/client_channel/client_channel.cc | 7 +++++-- .../ext/filters/client_channel/lb_policy.cc | 19 +++++++++++++++++-- .../ext/filters/client_channel/lb_policy.h | 4 +++- .../client_channel/lb_policy/xds/xds.cc | 3 --- .../ext/filters/client_channel/resolver.h | 14 +++++++++++--- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 40f8cef522b..a67792fcd37 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1435,8 +1435,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) std::move(target_uri), ProcessResolverResultLocked, this, error)); grpc_channel_args_destroy(new_args); if (*error != GRPC_ERROR_NONE) { - // Before we return, shut down the resolving LB policy, which destroys - // the ClientChannelControlHelper and therefore unrefs the channel stack. + // Orphan the resolving LB policy and flush the exec_ctx to ensure + // that it finishes shutting down. This ensures that if we are + // failing, we destroy the ClientChannelControlHelper (and thus + // unref the channel stack) before we return. // TODO(roth): This is not a complete solution, because it only // catches the case where channel stack initialization fails in this // particular filter. If there is a failure in a different filter, we @@ -1444,6 +1446,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) // in practice, there are no other filters that can cause failures in // channel stack initialization, so this works for now. resolving_lb_policy_.reset(); + ExecCtx::Get()->Flush(); } else { grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), interested_parties_); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 3207f888044..3e4d3703c82 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -43,8 +43,23 @@ LoadBalancingPolicy::~LoadBalancingPolicy() { } void LoadBalancingPolicy::Orphan() { - ShutdownLocked(); - Unref(); + // Invoke ShutdownAndUnrefLocked() inside of the combiner. + // TODO(roth): Is this actually needed? We should already be in the + // combiner here. Note that if we directly call ShutdownLocked(), + // then we can probably remove the hack whereby the helper is + // destroyed at shutdown instead of at destruction. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); +} + +void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, + grpc_error* ignored) { + LoadBalancingPolicy* policy = static_cast(arg); + policy->ShutdownLocked(); + policy->channel_control_helper_.reset(); + policy->Unref(); } // diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index ecc235bb71b..c21e9d90ec4 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -282,7 +282,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties() const { return interested_parties_; } - // Note: This must be invoked while holding the combiner. void Orphan() override; // A picker that returns PICK_QUEUE for all picks. @@ -323,6 +322,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { // Note: LB policies MUST NOT call any method on the helper from their // constructor. + // Note: This will return null after ShutdownLocked() has been called. ChannelControlHelper* channel_control_helper() const { return channel_control_helper_.get(); } @@ -331,6 +331,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void ShutdownLocked() GRPC_ABSTRACT; private: + static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored); + /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; /// Owned pointer to interested parties in load balancing decisions. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index ca6ab216515..74660cec92b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1989,9 +1989,6 @@ void XdsLb::LocalityMap::LocalityEntry::ShutdownLocked() { parent_->interested_parties()); pending_child_policy_.reset(); } - // Drop our ref to the child's picker, in case it's holding a ref to - // the child. - picker_ref_.reset(); } void XdsLb::LocalityMap::LocalityEntry::ResetBackoffLocked() { diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 829a860040a..87a4442d75b 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -117,10 +117,12 @@ class Resolver : public InternallyRefCounted { /// implementations. At that point, this method can go away. virtual void ResetBackoffLocked() {} - // Note: This must be invoked while holding the combiner. void Orphan() override { - ShutdownLocked(); - Unref(); + // Invoke ShutdownAndUnrefLocked() inside of the combiner. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&Resolver::ShutdownAndUnrefLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); } GRPC_ABSTRACT_BASE_CLASS @@ -145,6 +147,12 @@ class Resolver : public InternallyRefCounted { ResultHandler* result_handler() const { return result_handler_.get(); } private: + static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { + Resolver* resolver = static_cast(arg); + resolver->ShutdownLocked(); + resolver->Unref(); + } + UniquePtr result_handler_; grpc_combiner* combiner_; }; From 1def76bf1d789ac6bc3d6521ee5742769eab1b60 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 17 Jun 2019 17:16:46 -0700 Subject: [PATCH 364/676] Add Makefile --- BUILD.gn | 3 + CMakeLists.txt | 76 +++++++++-------- Makefile | 84 +++++++++++-------- src/python/grpcio/grpc_core_dependencies.py | 1 + .../generated/sources_and_headers.json | 34 ++++---- tools/run_tests/generated/tests.json | 48 +++++------ 6 files changed, 135 insertions(+), 111 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index e5396f51426..2ec4609c06d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -622,6 +622,8 @@ config("grpc_config") { "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/threadpool/mpmcqueue.cc", + "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.cc", @@ -1267,6 +1269,7 @@ config("grpc_config") { "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index c43039a4fed..7438eaf37cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,7 +378,6 @@ add_dependencies(buildtests_c memory_usage_test) endif() add_dependencies(buildtests_c message_compress_test) add_dependencies(buildtests_c minimal_stack_is_minimal_test) -add_dependencies(buildtests_c mpmcqueue_test) add_dependencies(buildtests_c multiple_server_queues_test) add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) @@ -664,6 +663,7 @@ add_dependencies(buildtests_cxx memory_test) add_dependencies(buildtests_cxx message_allocator_end2end_test) add_dependencies(buildtests_cxx metrics_client) add_dependencies(buildtests_cxx mock_test) +add_dependencies(buildtests_cxx mpmcqueue_test) add_dependencies(buildtests_cxx nonblocking_test) add_dependencies(buildtests_cxx noop-benchmark) add_dependencies(buildtests_cxx optional_test) @@ -9362,40 +9362,6 @@ target_link_libraries(minimal_stack_is_minimal_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(mpmcqueue_test - test/core/iomgr/mpmcqueue_test.cc -) - - -target_include_directories(mpmcqueue_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(mpmcqueue_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(mpmcqueue_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(mpmcqueue_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(multiple_server_queues_test test/core/end2end/multiple_server_queues_test.cc ) @@ -15035,6 +15001,46 @@ target_link_libraries(mock_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(mpmcqueue_test + test/core/iomgr/mpmcqueue_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(mpmcqueue_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(mpmcqueue_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index a188ae668d9..717402673b4 100644 --- a/Makefile +++ b/Makefile @@ -1092,7 +1092,6 @@ memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test -mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test @@ -1241,6 +1240,7 @@ memory_test: $(BINDIR)/$(CONFIG)/memory_test message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test metrics_client: $(BINDIR)/$(CONFIG)/metrics_client mock_test: $(BINDIR)/$(CONFIG)/mock_test +mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark optional_test: $(BINDIR)/$(CONFIG)/optional_test @@ -1514,7 +1514,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/memory_usage_test \ $(BINDIR)/$(CONFIG)/message_compress_test \ $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \ - $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/multiple_server_queues_test \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ @@ -1706,6 +1705,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ + $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ $(BINDIR)/$(CONFIG)/optional_test \ @@ -1867,6 +1867,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ + $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ $(BINDIR)/$(CONFIG)/optional_test \ @@ -2105,8 +2106,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 ) $(E) "[RUN] Testing minimal_stack_is_minimal_test" $(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_test failed ; exit 1 ) - $(E) "[RUN] Testing mpmcqueue_test" - $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing multiple_server_queues_test" $(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 ) $(E) "[RUN] Testing murmur_hash_test" @@ -2369,6 +2368,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing mock_test" $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 ) + $(E) "[RUN] Testing mpmcqueue_test" + $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing nonblocking_test" $(Q) $(BINDIR)/$(CONFIG)/nonblocking_test || ( echo test nonblocking_test failed ; exit 1 ) $(E) "[RUN] Testing noop-benchmark" @@ -12120,38 +12121,6 @@ endif endif -MPMCQUEUE_TEST_SRC = \ - test/core/iomgr/mpmcqueue_test.cc \ - -MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/mpmcqueue_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(MPMCQUEUE_TEST_OBJS:.o=.dep) -endif -endif - - MULTIPLE_SERVER_QUEUES_TEST_SRC = \ test/core/end2end/multiple_server_queues_test.cc \ @@ -17994,6 +17963,49 @@ endif endif +MPMCQUEUE_TEST_SRC = \ + test/core/iomgr/mpmcqueue_test.cc \ + +MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/mpmcqueue_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.5.0+. + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(PROTOBUF_DEP) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MPMCQUEUE_TEST_OBJS:.o=.dep) +endif +endif + + NONBLOCKING_TEST_SRC = \ test/cpp/end2end/nonblocking_test.cc \ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2619ccf9740..fc9979f418e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -158,6 +158,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', + 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6860b8b42ef..3fad15ca046 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1626,22 +1626,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "mpmcqueue_test", - "src": [ - "test/core/iomgr/mpmcqueue_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -4311,6 +4295,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "mpmcqueue_test", + "src": [ + "test/core/iomgr/mpmcqueue_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 8a5d0a60e82..681d88fd483 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -1959,30 +1959,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "mpmcqueue_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -5021,6 +4997,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "mpmcqueue_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From e291396644248a677f86d5bfd8b8df5c19308abf Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Jun 2019 22:59:55 -0700 Subject: [PATCH 365/676] Cap deadline to 99999999 seconds on wire --- src/core/lib/transport/timeout_encoding.cc | 7 +++++++ src/core/lib/transport/timeout_encoding.h | 5 +++-- test/core/transport/timeout_encoding_test.cc | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc index fe22c15fa6d..26d4b4a426f 100644 --- a/src/core/lib/transport/timeout_encoding.cc +++ b/src/core/lib/transport/timeout_encoding.cc @@ -44,6 +44,9 @@ static int64_t round_up_to_three_sig_figs(int64_t x) { /* encode our minimum viable timeout value */ static void enc_tiny(char* buffer) { memcpy(buffer, "1n", 3); } +/* encode our maximum timeout value, about 1157 days */ +static void enc_huge(char* buffer) { memcpy(buffer, "99999999S", 10); } + static void enc_ext(char* buffer, int64_t value, char ext) { int n = int64_ttoa(value, buffer); buffer[n] = ext; @@ -51,6 +54,7 @@ static void enc_ext(char* buffer, int64_t value, char ext) { } static void enc_seconds(char* buffer, int64_t sec) { + sec = round_up_to_three_sig_figs(sec); if (sec % 3600 == 0) { enc_ext(buffer, sec / 3600, 'H'); } else if (sec % 60 == 0) { @@ -74,10 +78,13 @@ static void enc_millis(char* buffer, int64_t x) { } void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer) { + const grpc_millis kMaxTimeout = 99999999000; if (timeout <= 0) { enc_tiny(buffer); } else if (timeout < 1000 * GPR_MS_PER_SEC) { enc_millis(buffer, timeout); + } else if (timeout >= kMaxTimeout) { + enc_huge(buffer); } else { enc_seconds(buffer, timeout / GPR_MS_PER_SEC + (timeout % GPR_MS_PER_SEC != 0)); diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h index cc0d37452fd..c87ff39d491 100644 --- a/src/core/lib/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -27,10 +27,11 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/exec_ctx.h" -#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) +#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE 10 /* Encode/decode timeouts to the GRPC over HTTP/2 format; - encoding may round up arbitrarily */ + encoding may round up arbitrarily. If the timeout is larger than about 1157 + days, it will be capped and "99999999S" will be sent on the wire. */ void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer); int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout); diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc index 22e68fe5540..61c3061d0c1 100644 --- a/test/core/transport/timeout_encoding_test.cc +++ b/test/core/transport/timeout_encoding_test.cc @@ -62,6 +62,9 @@ void test_encoding(void) { assert_encodes_as(20 * 60 * GPR_MS_PER_SEC, "20M"); assert_encodes_as(60 * 60 * GPR_MS_PER_SEC, "1H"); assert_encodes_as(10 * 60 * 60 * GPR_MS_PER_SEC, "10H"); + assert_encodes_as(60 * 60 * GPR_MS_PER_SEC - 100, "1H"); + assert_encodes_as(100 * 60 * 60 * GPR_MS_PER_SEC, "100H"); + assert_encodes_as(100000000000, "99999999S"); } static void assert_decodes_as(const char* buffer, grpc_millis expected) { From 61886e0d73ecadb4fddab664c9ea6c0d80ca88dc Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 18 Jun 2019 12:06:17 -0400 Subject: [PATCH 366/676] Eliminate a branch in Delete for grpc_core::UniquePtr. This is showing up in microbenchmarks in the StringView PR, becacuse strdup() retruns a grpc_core::UniquePtr now. Removing the branch lowers the difference. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 4 +-- .../client_channel/lb_policy/xds/xds.cc | 4 +-- .../filters/client_channel/retry_throttle.h | 5 ++- src/core/lib/gprpp/memory.h | 35 ++++++++++++++----- src/core/lib/slice/slice_hash_table.h | 10 ++---- src/core/lib/slice/slice_weak_hash_table.h | 9 ++--- .../tsi/ssl/session_cache/ssl_session_cache.h | 9 ++--- 7 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index dad10f0ce86..886f0c59a7a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -161,9 +161,7 @@ class GrpcLb : public LoadBalancingPolicy { bool seen_serverlist() const { return seen_serverlist_; } private: - // So Delete() can access our private dtor. - template - friend void grpc_core::Delete(T*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE ~BalancerCallState(); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index ca6ab216515..c67fe6c1b20 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -185,9 +185,7 @@ class XdsLb : public LoadBalancingPolicy { bool seen_initial_response() const { return seen_initial_response_; } private: - // So Delete() can access our private dtor. - template - friend void grpc_core::Delete(T*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE ~BalancerCallState(); diff --git a/src/core/ext/filters/client_channel/retry_throttle.h b/src/core/ext/filters/client_channel/retry_throttle.h index fddafcd903e..9e2fff56d24 100644 --- a/src/core/ext/filters/client_channel/retry_throttle.h +++ b/src/core/ext/filters/client_channel/retry_throttle.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted.h" namespace grpc_core { @@ -42,9 +43,7 @@ class ServerRetryThrottleData : public RefCounted { intptr_t milli_token_ratio() const { return milli_token_ratio_; } private: - // So Delete() can call our private dtor. - template - friend void grpc_core::Delete(T*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE ~ServerRetryThrottleData(); diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index 70ad430c51d..2e7658e4866 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -29,14 +30,17 @@ // Add this to a class that want to use Delete(), but has a private or // protected destructor. -#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ - template \ - friend void grpc_core::Delete(T*); +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \ + template \ + friend void ::grpc_core::Delete(_Delete_T*); \ + template \ + friend void ::grpc_core::Delete(_Delete_T*); + // Add this to a class that want to use New(), but has a private or // protected constructor. -#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ - template \ - friend T* grpc_core::New(Args&&...); +#define GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \ + template \ + friend _New_T* grpc_core::New(_New_Args&&...); namespace grpc_core { @@ -48,17 +52,30 @@ inline T* New(Args&&... args) { } // Alternative to delete, since we cannot use it (for fear of libstdc++) -template +// We cannot add a default value for can_be_null, because they are used as +// as friend template methods where we cannot define a default value. +// Instead we simply define two variants, one with and one without the boolean +// argument. +template inline void Delete(T* p) { - if (p == nullptr) return; + GPR_DEBUG_ASSERT(can_be_null || p != nullptr); + if (can_be_null && p == nullptr) return; p->~T(); gpr_free(p); } +template +inline void Delete(T* p) { + Delete(p); +} template class DefaultDelete { public: - void operator()(T* p) { Delete(p); } + void operator()(T* p) { + // std::unique_ptr is gauranteed not to call the deleter + // if the pointer is nullptr. + Delete(p); + } }; template > diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h index c20eca9db77..bd003c2c5b4 100644 --- a/src/core/lib/slice/slice_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -25,6 +25,7 @@ #include #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/slice/slice_internal.h" @@ -77,13 +78,8 @@ class SliceHashTable : public RefCounted> { static int Cmp(const SliceHashTable& a, const SliceHashTable& b); private: - // So New() can call our private ctor. - template - friend T2* New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void Delete(T2*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp); virtual ~SliceHashTable(); diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h index 8c5562bf196..bd59a4c2e48 100644 --- a/src/core/lib/slice/slice_weak_hash_table.h +++ b/src/core/lib/slice/slice_weak_hash_table.h @@ -61,13 +61,8 @@ class SliceWeakHashTable : public RefCounted> { } private: - // So New() can call our private ctor. - template - friend T2* New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void Delete(T2*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE SliceWeakHashTable() = default; ~SliceWeakHashTable() = default; diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.h b/src/core/tsi/ssl/session_cache/ssl_session_cache.h index 37fa2d124c9..16ab97714a7 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.h +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.h @@ -67,13 +67,8 @@ class SslSessionLRUCache : public grpc_core::RefCounted { SslSessionPtr Get(const char* key); private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void grpc_core::Delete(T*); + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + GRPC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE class Node; From e5de1e5e254c00c912032eef86399e2c911771fc Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Jun 2019 10:12:41 -0700 Subject: [PATCH 367/676] Update global interceptor comment and raise exception --- src/objective-c/GRPCClient/GRPCCall+Interceptor.h | 11 +++++++++-- src/objective-c/GRPCClient/GRPCCall+Interceptor.m | 10 ++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.h b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h index 4183e0aa20e..e6da2a7bda4 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Interceptor.h +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.h @@ -24,8 +24,15 @@ @interface GRPCCall2 (Interceptor) -+ (void)registerGlobalInterceptor:(id)interceptorFactory; +/** + * Register a global interceptor's factory in the current process. Only one interceptor can be + * registered in a process. If another one attempts to be registered, an exception will be raised. + */ ++ (void)registerGlobalInterceptor:(nonnull id)interceptorFactory; -+ (id)globalInterceptorFactory; +/** + * Get the global interceptor's factory. + */ ++ (nullable id)globalInterceptorFactory; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.m b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m index b1cad75d4f3..eed402f9c7e 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Interceptor.m +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m @@ -26,18 +26,16 @@ static dispatch_once_t onceToken; @implementation GRPCCall2 (Interceptor) + (void)registerGlobalInterceptor:(id)interceptorFactory { + if (interceptorFactory == nil) { + return; + } dispatch_once(&onceToken, ^{ globalInterceptorLock = [[NSLock alloc] init]; }); [globalInterceptorLock lock]; - NSAssert(globalInterceptorFactory == nil, - @"Global interceptor is already registered. Only one global interceptor can be " - @"registered in a process"); if (globalInterceptorFactory != nil) { - NSLog( - @"Global interceptor is already registered. Only one global interceptor can be registered " - @"in a process"); [globalInterceptorLock unlock]; + [NSException raise:NSInternalInconsistencyException format:@"Global interceptor is already registered. Only one global interceptor can be registered in a process."]; return; } From a9ad58e0374ab83b511c6be5be45ae7f75f74b95 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Jun 2019 10:13:13 -0700 Subject: [PATCH 368/676] Fix global interceptor tests --- src/objective-c/GRPCClient/GRPCCall.m | 48 +++---- .../tests/InteropTests/InteropTests.m | 133 ++++++++++++++---- 2 files changed, 125 insertions(+), 56 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 5280f8d01f4..c25e8daaf4c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -155,11 +155,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; GRPCInterceptor *interceptor = [globalInterceptorFactory createInterceptorWithManager:manager]; - NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", - globalInterceptorFactory); - if (interceptor == nil) { - NSLog(@"Failed to create interceptor from factory: %@", globalInterceptorFactory); - } else { + if (interceptor != nil) { [internalCall setResponseHandler:interceptor]; nextInterceptor = interceptor; nextManager = manager; @@ -168,35 +164,31 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Finally initialize the interceptors in the chain NSArray *interceptorFactories = _actualCallOptions.interceptorFactories; - if (interceptorFactories.count == 0) { + for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { + GRPCInterceptorManager *manager = + [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; + GRPCInterceptor *interceptor = + [interceptorFactories[i] createInterceptorWithManager:manager]; + NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", + interceptorFactories[i]); + if (interceptor == nil) { + NSLog(@"Failed to create interceptor from factory: %@", interceptorFactories[i]); + continue; + } if (nextManager == nil) { - [internalCall setResponseHandler:_responseHandler]; + [internalCall setResponseHandler:interceptor]; } else { - [nextManager setPreviousInterceptor:_responseHandler]; + [nextManager setPreviousInterceptor:interceptor]; } + nextInterceptor = interceptor; + nextManager = manager; + } + if (nextManager == nil) { + [internalCall setResponseHandler:_responseHandler]; } else { - for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { - GRPCInterceptorManager *manager = - [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; - GRPCInterceptor *interceptor = - [interceptorFactories[i] createInterceptorWithManager:manager]; - NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", - interceptorFactories[i]); - if (interceptor == nil) { - NSLog(@"Failed to create interceptor from factory: %@", interceptorFactories[i]); - continue; - } - if (nextManager == nil) { - [internalCall setResponseHandler:interceptor]; - } else { - [nextManager setPreviousInterceptor:interceptor]; - } - nextInterceptor = interceptor; - nextManager = manager; - } - [nextManager setPreviousInterceptor:_responseHandler]; } + _firstInterceptor = nextInterceptor; } diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 2c54fb80f3d..235fcaed483 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -121,7 +121,7 @@ initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue @end -@interface HookIntercetpor : GRPCInterceptor +@interface HookInterceptor : GRPCInterceptor - (instancetype) initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @@ -144,6 +144,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @end @implementation HookInterceptorFactory { +@protected void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); void (^_writeDataHook)(id data, GRPCInterceptorManager *manager); @@ -190,7 +191,7 @@ initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue } - (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { - return [[HookIntercetpor alloc] initWithInterceptorManager:interceptorManager + return [[HookInterceptor alloc] initWithInterceptorManager:interceptorManager requestDispatchQueue:_requestDispatchQueue responseDispatchQueue:_responseDispatchQueue startHook:_startHook @@ -205,7 +206,7 @@ initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue @end -@implementation HookIntercetpor { +@implementation HookInterceptor { void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); void (^_writeDataHook)(id data, GRPCInterceptorManager *manager); @@ -315,6 +316,92 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @end +@interface GlobalInterceptorFactory : HookInterceptorFactory + +@property BOOL enabled; + +- (instancetype)initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue; + +- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook +receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; + +@end + +@implementation GlobalInterceptorFactory + +- (instancetype)initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue + responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue { + _enabled = NO; + return [super initWithRequestDispatchQueue:requestDispatchQueue + responseDispatchQueue:responseDispatchQueue + startHook:nil + writeDataHook:nil + finishHook:nil + receiveNextMessagesHook:nil + responseHeaderHook:nil + responseDataHook:nil + responseCloseHook:nil + didWriteDataHook:nil]; +} + +- (GRPCInterceptor *)createInterceptorWithManager:(GRPCInterceptorManager *)interceptorManager { + if (_enabled) { + return [[HookInterceptor alloc] initWithInterceptorManager:interceptorManager + requestDispatchQueue:_requestDispatchQueue + responseDispatchQueue:_responseDispatchQueue + startHook:_startHook + writeDataHook:_writeDataHook + finishHook:_finishHook + receiveNextMessagesHook:_receiveNextMessagesHook + responseHeaderHook:_responseHeaderHook + responseDataHook:_responseDataHook + responseCloseHook:_responseCloseHook + didWriteDataHook:_didWriteDataHook]; + } else { + return nil; + } +} + +- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager))startHook + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook +receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { + _startHook = startHook; + _writeDataHook = writeDataHook; + _finishHook = finishHook; + _receiveNextMessagesHook = receiveNextMessagesHook; + _responseHeaderHook = responseHeaderHook; + _responseDataHook = responseDataHook; + _responseCloseHook = responseCloseHook; + _didWriteDataHook = didWriteDataHook; +} + +@end + +static GlobalInterceptorFactory *globalInterceptorFactory = nil; +static dispatch_once_t initGlobalInterceptorFactory; + #pragma mark Tests @implementation InteropTests { @@ -358,6 +445,13 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager #ifdef GRPC_CFSTREAM setenv(kCFStreamVarName, "1", 1); #endif + + dispatch_once(&initGlobalInterceptorFactory, ^{ + dispatch_queue_t globalInterceptorQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + globalInterceptorFactory = [[GlobalInterceptorFactory alloc] initWithRequestDispatchQueue:globalInterceptorQueue + responseDispatchQueue:globalInterceptorQueue]; + [GRPCCall2 registerGlobalInterceptor:globalInterceptorFactory]; + }); } - (void)setUp { @@ -1531,10 +1625,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block NSUInteger responseDataCount = 0; __block NSUInteger responseCloseCount = 0; __block NSUInteger didWriteDataCount = 0; - id factory = [[HookInterceptorFactory alloc] - initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { startCount++; XCTAssertEqualObjects(requestOptions.host, [[self class] host]); @@ -1585,7 +1676,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager options.PEMRootCertificates = [[self class] PEMRootCertificates]; options.hostNameOverride = [[self class] hostNameOverride]; options.flowControlEnabled = YES; - [GRPCCall2 registerGlobalInterceptor:factory]; + globalInterceptorFactory.enabled = YES; __block BOOL canWriteData = NO; __block GRPCStreamingProtoCall *call = [_service @@ -1631,6 +1722,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager XCTAssertEqual(responseDataCount, 4); XCTAssertEqual(responseCloseCount, 1); XCTAssertEqual(didWriteDataCount, 4); + globalInterceptorFactory.enabled = NO; } - (void)testConflictingGlobalInterceptors { @@ -1645,24 +1737,11 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager responseDataHook:nil responseCloseHook:nil didWriteDataHook:nil]; - id factory2 = [[HookInterceptorFactory alloc] - initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - startHook:nil - writeDataHook:nil - finishHook:nil - receiveNextMessagesHook:nil - responseHeaderHook:nil - responseDataHook:nil - responseCloseHook:nil - didWriteDataHook:nil]; - - [GRPCCall2 registerGlobalInterceptor:factory]; @try { - [GRPCCall2 registerGlobalInterceptor:factory2]; + [GRPCCall2 registerGlobalInterceptor:factory]; XCTFail(@"Did not receive an exception when registering global interceptor the second time"); } @catch (NSException *exception) { - NSLog(@"Received exception as expected: %@", exception); + // Do nothing; test passes } } @@ -1731,10 +1810,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager __block NSUInteger globalResponseCloseCount = 0; __block NSUInteger globalDidWriteDataCount = 0; - id globalFactory = [[HookInterceptorFactory alloc] - initWithRequestDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - responseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL) - startHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, + [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager) { globalStartCount++; XCTAssertEqualObjects(requestOptions.host, [[self class] host]); @@ -1786,7 +1862,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager options.hostNameOverride = [[self class] hostNameOverride]; options.flowControlEnabled = YES; options.interceptorFactories = @[ factory ]; - [GRPCCall2 registerGlobalInterceptor:globalFactory]; + globalInterceptorFactory.enabled = YES; __block BOOL canWriteData = NO; __block GRPCStreamingProtoCall *call = [_service @@ -1834,6 +1910,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager XCTAssertEqual(globalResponseDataCount, 4); XCTAssertEqual(globalResponseCloseCount, 1); XCTAssertEqual(globalDidWriteDataCount, 4); + globalInterceptorFactory.enabled = NO; } @end From 7f327f1ca7b0bb2e744a9a198d8c4c6038772ccb Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 18 Jun 2019 10:33:02 -0700 Subject: [PATCH 369/676] Relax csharp deadline test --- src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs index 4158579194f..097db777a30 100644 --- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs +++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs @@ -108,8 +108,8 @@ namespace Grpc.Core.Tests var deadline = DateTime.UtcNow.AddDays(7); helper.UnaryHandler = new UnaryServerMethod((request, context) => { - Assert.IsTrue(context.Deadline < deadline.AddMinutes(1)); - Assert.IsTrue(context.Deadline > deadline.AddMinutes(-1)); + Assert.IsTrue(context.Deadline < deadline.AddHours(1)); + Assert.IsTrue(context.Deadline > deadline.AddHours(-1)); return Task.FromResult("PASS"); }); From 6124a835d4b130f385e57e1e5b7840ed6766959b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Jun 2019 09:33:05 -0700 Subject: [PATCH 370/676] Revert "Hide ConnectedSubchannel from LB policy API." --- .../filters/client_channel/client_channel.cc | 420 +++++------------- .../ext/filters/client_channel/lb_policy.h | 2 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 9 +- .../lb_policy/pick_first/pick_first.cc | 30 +- .../lb_policy/round_robin/round_robin.cc | 20 +- .../lb_policy/subchannel_list.h | 126 ++++-- .../client_channel/lb_policy/xds/xds.cc | 2 +- .../ext/filters/client_channel/subchannel.cc | 23 +- .../ext/filters/client_channel/subchannel.h | 71 +-- .../client_channel/subchannel_interface.h | 45 +- src/core/lib/gprpp/map.h | 28 -- src/core/lib/transport/metadata.cc | 5 - test/core/gprpp/map_test.cc | 29 -- test/core/util/test_lb_policies.cc | 2 +- 14 files changed, 298 insertions(+), 514 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a67792fcd37..0b612e67a33 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -147,9 +147,6 @@ class ChannelData { return service_config_; } - RefCountedPtr GetConnectedSubchannelInDataPlane( - SubchannelInterface* subchannel) const; - grpc_connectivity_state CheckConnectivityState(bool try_to_connect); void AddExternalConnectivityWatcher(grpc_polling_entity pollent, grpc_connectivity_state* state, @@ -164,9 +161,9 @@ class ChannelData { } private: - class SubchannelWrapper; class ConnectivityStateAndPickerSetter; class ServiceConfigSetter; + class GrpcSubchannel; class ClientChannelControlHelper; class ExternalConnectivityWatcher { @@ -265,14 +262,7 @@ class ChannelData { UniquePtr health_check_service_name_; RefCountedPtr saved_service_config_; bool received_first_resolver_result_ = false; - // The number of SubchannelWrapper instances referencing a given Subchannel. Map subchannel_refcount_map_; - // Pending ConnectedSubchannel updates for each SubchannelWrapper. - // Updates are queued here in the control plane combiner and then applied - // in the data plane combiner when the picker is updated. - Map, RefCountedPtr, - RefCountedPtrLess> - pending_subchannel_updates_; // // Fields accessed from both data plane and control plane combiners. @@ -716,247 +706,6 @@ class CallData { grpc_metadata_batch send_trailing_metadata_; }; -// -// ChannelData::SubchannelWrapper -// - -// This class is a wrapper for Subchannel that hides details of the -// channel's implementation (such as the health check service name and -// connected subchannel) from the LB policy API. -// -// Note that no synchronization is needed here, because even if the -// underlying subchannel is shared between channels, this wrapper will only -// be used within one channel, so it will always be synchronized by the -// control plane combiner. -class ChannelData::SubchannelWrapper : public SubchannelInterface { - public: - SubchannelWrapper(ChannelData* chand, Subchannel* subchannel, - UniquePtr health_check_service_name) - : SubchannelInterface(&grpc_client_channel_routing_trace), - chand_(chand), - subchannel_(subchannel), - health_check_service_name_(std::move(health_check_service_name)) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: creating subchannel wrapper %p for subchannel %p", - chand, this, subchannel_); - } - GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper"); - auto* subchannel_node = subchannel_->channelz_node(); - if (subchannel_node != nullptr) { - intptr_t subchannel_uuid = subchannel_node->uuid(); - auto it = chand_->subchannel_refcount_map_.find(subchannel_); - if (it == chand_->subchannel_refcount_map_.end()) { - chand_->channelz_node_->AddChildSubchannel(subchannel_uuid); - it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first; - } - ++it->second; - } - } - - ~SubchannelWrapper() { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: destroying subchannel wrapper %p for subchannel %p", - chand_, this, subchannel_); - } - auto* subchannel_node = subchannel_->channelz_node(); - if (subchannel_node != nullptr) { - intptr_t subchannel_uuid = subchannel_node->uuid(); - auto it = chand_->subchannel_refcount_map_.find(subchannel_); - GPR_ASSERT(it != chand_->subchannel_refcount_map_.end()); - --it->second; - if (it->second == 0) { - chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid); - chand_->subchannel_refcount_map_.erase(it); - } - } - GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); - GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "SubchannelWrapper"); - } - - grpc_connectivity_state CheckConnectivityState() override { - RefCountedPtr connected_subchannel; - grpc_connectivity_state connectivity_state = - subchannel_->CheckConnectivityState(health_check_service_name_.get(), - &connected_subchannel); - MaybeUpdateConnectedSubchannel(std::move(connected_subchannel)); - return connectivity_state; - } - - void WatchConnectivityState( - grpc_connectivity_state initial_state, - UniquePtr watcher) override { - auto& watcher_wrapper = watcher_map_[watcher.get()]; - GPR_ASSERT(watcher_wrapper == nullptr); - watcher_wrapper = New( - std::move(watcher), Ref(DEBUG_LOCATION, "WatcherWrapper")); - subchannel_->WatchConnectivityState( - initial_state, - UniquePtr(gpr_strdup(health_check_service_name_.get())), - OrphanablePtr( - watcher_wrapper)); - } - - void CancelConnectivityStateWatch( - ConnectivityStateWatcherInterface* watcher) override { - auto it = watcher_map_.find(watcher); - GPR_ASSERT(it != watcher_map_.end()); - subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(), - it->second); - watcher_map_.erase(it); - } - - void AttemptToConnect() override { subchannel_->AttemptToConnect(); } - - void ResetBackoff() override { subchannel_->ResetBackoff(); } - - const grpc_channel_args* channel_args() override { - return subchannel_->channel_args(); - } - - // Caller must be holding the control-plane combiner. - ConnectedSubchannel* connected_subchannel() const { - return connected_subchannel_.get(); - } - - // Caller must be holding the data-plane combiner. - ConnectedSubchannel* connected_subchannel_in_data_plane() const { - return connected_subchannel_in_data_plane_.get(); - } - void set_connected_subchannel_in_data_plane( - RefCountedPtr connected_subchannel) { - connected_subchannel_in_data_plane_ = std::move(connected_subchannel); - } - - private: - // Subchannel and SubchannelInterface have different interfaces for - // their respective ConnectivityStateWatcherInterface classes. - // The one in Subchannel updates the ConnectedSubchannel along with - // the state, whereas the one in SubchannelInterface does not expose - // the ConnectedSubchannel. - // - // This wrapper provides a bridge between the two. It implements - // Subchannel::ConnectivityStateWatcherInterface and wraps - // the instance of SubchannelInterface::ConnectivityStateWatcherInterface - // that was passed in by the LB policy. We pass an instance of this - // class to the underlying Subchannel, and when we get updates from - // the subchannel, we pass those on to the wrapped watcher to return - // the update to the LB policy. This allows us to set the connected - // subchannel before passing the result back to the LB policy. - class WatcherWrapper : public Subchannel::ConnectivityStateWatcherInterface { - public: - WatcherWrapper( - UniquePtr - watcher, - RefCountedPtr parent) - : watcher_(std::move(watcher)), parent_(std::move(parent)) {} - - ~WatcherWrapper() { parent_.reset(DEBUG_LOCATION, "WatcherWrapper"); } - - void Orphan() override { Unref(); } - - void OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) override { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: connectivity change for subchannel wrapper %p " - "subchannel %p (connected_subchannel=%p state=%s); " - "hopping into combiner", - parent_->chand_, parent_.get(), parent_->subchannel_, - connected_subchannel.get(), - grpc_connectivity_state_name(new_state)); - } - // Will delete itself. - New(Ref(), new_state, std::move(connected_subchannel)); - } - - grpc_pollset_set* interested_parties() override { - return watcher_->interested_parties(); - } - - private: - class Updater { - public: - Updater(RefCountedPtr parent, - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) - : parent_(std::move(parent)), - state_(new_state), - connected_subchannel_(std::move(connected_subchannel)) { - GRPC_CLOSURE_INIT( - &closure_, ApplyUpdateInControlPlaneCombiner, this, - grpc_combiner_scheduler(parent_->parent_->chand_->combiner_)); - GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); - } - - private: - static void ApplyUpdateInControlPlaneCombiner(void* arg, - grpc_error* error) { - Updater* self = static_cast(arg); - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: processing connectivity change in combiner " - "for subchannel wrapper %p subchannel %p " - "(connected_subchannel=%p state=%s)", - self->parent_->parent_->chand_, self->parent_->parent_.get(), - self->parent_->parent_->subchannel_, - self->connected_subchannel_.get(), - grpc_connectivity_state_name(self->state_)); - } - self->parent_->parent_->MaybeUpdateConnectedSubchannel( - std::move(self->connected_subchannel_)); - self->parent_->watcher_->OnConnectivityStateChange(self->state_); - Delete(self); - } - - RefCountedPtr parent_; - grpc_connectivity_state state_; - RefCountedPtr connected_subchannel_; - grpc_closure closure_; - }; - - UniquePtr watcher_; - RefCountedPtr parent_; - }; - - void MaybeUpdateConnectedSubchannel( - RefCountedPtr connected_subchannel) { - // Update the connected subchannel only if the channel is not shutting - // down. This is because once the channel is shutting down, we - // ignore picker updates from the LB policy, which means that - // ConnectivityStateAndPickerSetter will never process the entries - // in chand_->pending_subchannel_updates_. So we don't want to add - // entries there that will never be processed, since that would - // leave dangling refs to the channel and prevent its destruction. - grpc_error* disconnect_error = chand_->disconnect_error(); - if (disconnect_error != GRPC_ERROR_NONE) return; - // Not shutting down, so do the update. - if (connected_subchannel_ != connected_subchannel) { - connected_subchannel_ = std::move(connected_subchannel); - // Record the new connected subchannel so that it can be updated - // in the data plane combiner the next time the picker is updated. - chand_->pending_subchannel_updates_[Ref( - DEBUG_LOCATION, "ConnectedSubchannelUpdate")] = connected_subchannel_; - } - } - - ChannelData* chand_; - Subchannel* subchannel_; - UniquePtr health_check_service_name_; - // Maps from the address of the watcher passed to us by the LB policy - // to the address of the WrapperWatcher that we passed to the underlying - // subchannel. This is needed so that when the LB policy calls - // CancelConnectivityStateWatch() with its watcher, we know the - // corresponding WrapperWatcher to cancel on the underlying subchannel. - Map watcher_map_; - // To be accessed only in the control plane combiner. - RefCountedPtr connected_subchannel_; - // To be accessed only in the data plane combiner. - RefCountedPtr connected_subchannel_in_data_plane_; -}; - // // ChannelData::ConnectivityStateAndPickerSetter // @@ -980,13 +729,10 @@ class ChannelData::ConnectivityStateAndPickerSetter { grpc_slice_from_static_string( GetChannelConnectivityStateChangeString(state))); } - // Grab any pending subchannel updates. - pending_subchannel_updates_ = - std::move(chand_->pending_subchannel_updates_); // Bounce into the data plane combiner to reset the picker. GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ConnectivityStateAndPickerSetter"); - GRPC_CLOSURE_INIT(&closure_, SetPickerInDataPlane, this, + GRPC_CLOSURE_INIT(&closure_, SetPicker, this, grpc_combiner_scheduler(chand->data_plane_combiner_)); GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); } @@ -1009,38 +755,16 @@ class ChannelData::ConnectivityStateAndPickerSetter { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } - static void SetPickerInDataPlane(void* arg, grpc_error* ignored) { + static void SetPicker(void* arg, grpc_error* ignored) { auto* self = static_cast(arg); - // Handle subchannel updates. - for (auto& p : self->pending_subchannel_updates_) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, - "chand=%p: updating subchannel wrapper %p data plane " - "connected_subchannel to %p", - self->chand_, p.first.get(), p.second.get()); - } - p.first->set_connected_subchannel_in_data_plane(std::move(p.second)); - } - // Swap out the picker. We hang on to the old picker so that it can - // be deleted in the control-plane combiner, since that's where we need - // to unref the subchannel wrappers that are reffed by the picker. - self->picker_.swap(self->chand_->picker_); + // Update picker. + self->chand_->picker_ = std::move(self->picker_); // Re-process queued picks. for (QueuedPick* pick = self->chand_->queued_picks_; pick != nullptr; pick = pick->next) { CallData::StartPickLocked(pick->elem, GRPC_ERROR_NONE); } - // Pop back into the control plane combiner to delete ourself, so - // that we make sure to unref subchannel wrappers there. This - // includes both the ones reffed by the old picker (now stored in - // self->picker_) and the ones in self->pending_subchannel_updates_. - GRPC_CLOSURE_INIT(&self->closure_, CleanUpInControlPlane, self, - grpc_combiner_scheduler(self->chand_->combiner_)); - GRPC_CLOSURE_SCHED(&self->closure_, GRPC_ERROR_NONE); - } - - static void CleanUpInControlPlane(void* arg, grpc_error* ignored) { - auto* self = static_cast(arg); + // Clean up. GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack_, "ConnectivityStateAndPickerSetter"); Delete(self); @@ -1048,9 +772,6 @@ class ChannelData::ConnectivityStateAndPickerSetter { ChannelData* chand_; UniquePtr picker_; - Map, RefCountedPtr, - RefCountedPtrLess> - pending_subchannel_updates_; grpc_closure closure_; }; @@ -1225,6 +946,89 @@ void ChannelData::ExternalConnectivityWatcher::WatchConnectivityStateLocked( &self->chand_->state_tracker_, self->state_, &self->my_closure_); } +// +// ChannelData::GrpcSubchannel +// + +// This class is a wrapper for Subchannel that hides details of the +// channel's implementation (such as the health check service name) from +// the LB policy API. +// +// Note that no synchronization is needed here, because even if the +// underlying subchannel is shared between channels, this wrapper will only +// be used within one channel, so it will always be synchronized by the +// control plane combiner. +class ChannelData::GrpcSubchannel : public SubchannelInterface { + public: + GrpcSubchannel(ChannelData* chand, Subchannel* subchannel, + UniquePtr health_check_service_name) + : chand_(chand), + subchannel_(subchannel), + health_check_service_name_(std::move(health_check_service_name)) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "GrpcSubchannel"); + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + if (it == chand_->subchannel_refcount_map_.end()) { + chand_->channelz_node_->AddChildSubchannel(subchannel_uuid); + it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first; + } + ++it->second; + } + } + + ~GrpcSubchannel() { + auto* subchannel_node = subchannel_->channelz_node(); + if (subchannel_node != nullptr) { + intptr_t subchannel_uuid = subchannel_node->uuid(); + auto it = chand_->subchannel_refcount_map_.find(subchannel_); + GPR_ASSERT(it != chand_->subchannel_refcount_map_.end()); + --it->second; + if (it->second == 0) { + chand_->channelz_node_->RemoveChildSubchannel(subchannel_uuid); + chand_->subchannel_refcount_map_.erase(it); + } + } + GRPC_SUBCHANNEL_UNREF(subchannel_, "unref from LB"); + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "GrpcSubchannel"); + } + + grpc_connectivity_state CheckConnectivityState( + RefCountedPtr* connected_subchannel) + override { + RefCountedPtr tmp; + auto retval = subchannel_->CheckConnectivityState( + health_check_service_name_.get(), &tmp); + *connected_subchannel = std::move(tmp); + return retval; + } + + void WatchConnectivityState( + grpc_connectivity_state initial_state, + UniquePtr watcher) override { + subchannel_->WatchConnectivityState( + initial_state, + UniquePtr(gpr_strdup(health_check_service_name_.get())), + std::move(watcher)); + } + + void CancelConnectivityStateWatch( + ConnectivityStateWatcher* watcher) override { + subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(), + watcher); + } + + void AttemptToConnect() override { subchannel_->AttemptToConnect(); } + + void ResetBackoff() override { subchannel_->ResetBackoff(); } + + private: + ChannelData* chand_; + Subchannel* subchannel_; + UniquePtr health_check_service_name_; +}; + // // ChannelData::ClientChannelControlHelper // @@ -1262,8 +1066,8 @@ class ChannelData::ClientChannelControlHelper chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) return nullptr; - return MakeRefCounted( - chand_, subchannel, std::move(health_check_service_name)); + return MakeRefCounted(chand_, subchannel, + std::move(health_check_service_name)); } grpc_channel* CreateChannel(const char* target, @@ -1274,7 +1078,8 @@ class ChannelData::ClientChannelControlHelper void UpdateState( grpc_connectivity_state state, UniquePtr picker) override { - grpc_error* disconnect_error = chand_->disconnect_error(); + grpc_error* disconnect_error = + chand_->disconnect_error_.Load(MemoryOrder::ACQUIRE); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { const char* extra = disconnect_error == GRPC_ERROR_NONE ? "" @@ -1646,13 +1451,9 @@ grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) { } LoadBalancingPolicy::PickResult result = picker_->Pick(LoadBalancingPolicy::PickArgs()); - ConnectedSubchannel* connected_subchannel = nullptr; - if (result.subchannel != nullptr) { - SubchannelWrapper* subchannel = - static_cast(result.subchannel.get()); - connected_subchannel = subchannel->connected_subchannel(); - } - if (connected_subchannel != nullptr) { + if (result.connected_subchannel != nullptr) { + ConnectedSubchannel* connected_subchannel = + static_cast(result.connected_subchannel.get()); connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack); } else { if (result.error == GRPC_ERROR_NONE) { @@ -1695,10 +1496,6 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { } // Disconnect. if (op->disconnect_with_error != GRPC_ERROR_NONE) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) { - gpr_log(GPR_INFO, "chand=%p: channel shut down from API: %s", chand, - grpc_error_string(op->disconnect_with_error)); - } grpc_error* error = GRPC_ERROR_NONE; GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( &error, op->disconnect_with_error, MemoryOrder::ACQ_REL, @@ -1773,17 +1570,6 @@ void ChannelData::RemoveQueuedPick(QueuedPick* to_remove, } } -RefCountedPtr -ChannelData::GetConnectedSubchannelInDataPlane( - SubchannelInterface* subchannel) const { - SubchannelWrapper* subchannel_wrapper = - static_cast(subchannel); - ConnectedSubchannel* connected_subchannel = - subchannel_wrapper->connected_subchannel_in_data_plane(); - if (connected_subchannel == nullptr) return nullptr; - return connected_subchannel->Ref(); -} - void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { auto* chand = static_cast(arg); if (chand->resolving_lb_policy_ != nullptr) { @@ -3711,9 +3497,10 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { auto result = chand->picker()->Pick(pick_args); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, - "chand=%p calld=%p: LB pick returned %s (subchannel=%p, error=%s)", + "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " + "error=%s)", chand, calld, PickResultTypeName(result.type), - result.subchannel.get(), grpc_error_string(result.error)); + result.connected_subchannel.get(), grpc_error_string(result.error)); } switch (result.type) { case LoadBalancingPolicy::PickResult::PICK_TRANSIENT_FAILURE: { @@ -3755,16 +3542,11 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { break; default: // PICK_COMPLETE // Handle drops. - if (GPR_UNLIKELY(result.subchannel == nullptr)) { + if (GPR_UNLIKELY(result.connected_subchannel == nullptr)) { result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Call dropped by load balancing policy"); - } else { - // Grab a ref to the connected subchannel while we're still - // holding the data plane combiner. - calld->connected_subchannel_ = - chand->GetConnectedSubchannelInDataPlane(result.subchannel.get()); - GPR_ASSERT(calld->connected_subchannel_ != nullptr); } + calld->connected_subchannel_ = std::move(result.connected_subchannel); calld->lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready; calld->lb_recv_trailing_metadata_ready_user_data_ = diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index c21e9d90ec4..f98a41dee07 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -128,7 +128,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Used only if type is PICK_COMPLETE. Will be set to the selected /// subchannel, or nullptr if the LB policy decides to drop the call. - RefCountedPtr subchannel; + RefCountedPtr connected_subchannel; /// Used only if type is PICK_TRANSIENT_FAILURE. /// Error to be set when returning a transient failure. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index dad10f0ce86..a87dfda7321 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -575,12 +575,13 @@ GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) { result = child_picker_->Pick(args); // If pick succeeded, add LB token to initial metadata. if (result.type == PickResult::PICK_COMPLETE && - result.subchannel != nullptr) { + result.connected_subchannel != nullptr) { const grpc_arg* arg = grpc_channel_args_find( - result.subchannel->channel_args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); if (arg == nullptr) { - gpr_log(GPR_ERROR, "[grpclb %p picker %p] No LB token for subchannel %p", - parent_, this, result.subchannel.get()); + gpr_log(GPR_ERROR, + "[grpclb %p picker %p] No LB token for connected subchannel %p", + parent_, this, result.connected_subchannel.get()); abort(); } grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 8bf3d825b23..00036d8be64 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -28,6 +28,7 @@ #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -84,8 +85,9 @@ class PickFirst : public LoadBalancingPolicy { public: PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, + grpc_combiner* combiner, const grpc_channel_args& args) - : SubchannelList(policy, tracer, addresses, + : SubchannelList(policy, tracer, addresses, combiner, policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' @@ -109,18 +111,19 @@ class PickFirst : public LoadBalancingPolicy { class Picker : public SubchannelPicker { public: - explicit Picker(RefCountedPtr subchannel) - : subchannel_(std::move(subchannel)) {} + explicit Picker( + RefCountedPtr connected_subchannel) + : connected_subchannel_(std::move(connected_subchannel)) {} PickResult Pick(PickArgs args) override { PickResult result; result.type = PickResult::PICK_COMPLETE; - result.subchannel = subchannel_; + result.connected_subchannel = connected_subchannel_; return result; } private: - RefCountedPtr subchannel_; + RefCountedPtr connected_subchannel_; }; void ShutdownLocked() override; @@ -163,9 +166,6 @@ void PickFirst::ShutdownLocked() { void PickFirst::ExitIdleLocked() { if (shutdown_) return; if (idle_) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, "Pick First %p exiting idle", this); - } idle_ = false; if (subchannel_list_ == nullptr || subchannel_list_->num_subchannels() == 0) { @@ -200,7 +200,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current @@ -351,8 +351,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // some connectivity state notifications. if (connectivity_state == GRPC_CHANNEL_READY) { p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, - UniquePtr(New(subchannel()->Ref()))); + GRPC_CHANNEL_READY, UniquePtr(New( + connected_subchannel()->Ref()))); } else { // CONNECTING p->channel_control_helper()->UpdateState( connectivity_state, UniquePtr(New( @@ -447,13 +447,13 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } // Cases 1 and 2. - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); - } p->selected_ = this; p->channel_control_helper()->UpdateState( GRPC_CHANNEL_READY, - UniquePtr(New(subchannel()->Ref()))); + UniquePtr(New(connected_subchannel()->Ref()))); + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); + } } void PickFirst::PickFirstSubchannelData:: diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 04308ee254c..c6655c7d9bb 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -38,6 +38,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/static_metadata.h" @@ -105,8 +106,9 @@ class RoundRobin : public LoadBalancingPolicy { public: RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, + grpc_combiner* combiner, const grpc_channel_args& args) - : SubchannelList(policy, tracer, addresses, + : SubchannelList(policy, tracer, addresses, combiner, policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' @@ -153,7 +155,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobin* parent_; size_t last_picked_index_; - InlinedVector, 10> subchannels_; + InlinedVector, 10> subchannels_; }; void ShutdownLocked() override; @@ -178,9 +180,10 @@ RoundRobin::Picker::Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list) : parent_(parent) { for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { - RoundRobinSubchannelData* sd = subchannel_list->subchannel(i); - if (sd->connectivity_state() == GRPC_CHANNEL_READY) { - subchannels_.push_back(sd->subchannel()->Ref()); + auto* connected_subchannel = + subchannel_list->subchannel(i)->connected_subchannel(); + if (connected_subchannel != nullptr) { + subchannels_.push_back(connected_subchannel->Ref()); } } // For discussion on why we generate a random starting index for @@ -201,13 +204,14 @@ RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs args) { last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_round_robin_trace)) { gpr_log(GPR_INFO, - "[RR %p picker %p] returning index %" PRIuPTR ", subchannel=%p", + "[RR %p picker %p] returning index %" PRIuPTR + ", connected_subchannel=%p", parent_, this, last_picked_index_, subchannels_[last_picked_index_].get()); } PickResult result; result.type = PickResult::PICK_COMPLETE; - result.subchannel = subchannels_[last_picked_index_]; + result.connected_subchannel = subchannels_[last_picked_index_]; return result; } @@ -420,7 +424,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, *args.args); + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); if (latest_pending_subchannel_list_->num_subchannels() == 0) { // If the new list is empty, immediately promote the new list to the // current list and transition to TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 34cd0f549fe..7d70928a83c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -39,6 +39,7 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -63,7 +64,8 @@ class MySubchannelList }; */ -// All methods will be called from within the client_channel combiner. +// All methods with a Locked() suffix must be called from within the +// client_channel combiner. namespace grpc_core { @@ -91,13 +93,20 @@ class SubchannelData { // Returns a pointer to the subchannel. SubchannelInterface* subchannel() const { return subchannel_.get(); } + // Returns the connected subchannel. Will be null if the subchannel + // is not connected. + ConnectedSubchannelInterface* connected_subchannel() const { + return connected_subchannel_.get(); + } + // Synchronously checks the subchannel's connectivity state. // Must not be called while there is a connectivity notification // pending (i.e., between calling StartConnectivityWatchLocked() and // calling CancelConnectivityWatchLocked()). grpc_connectivity_state CheckConnectivityStateLocked() { GPR_ASSERT(pending_watcher_ == nullptr); - connectivity_state_ = subchannel_->CheckConnectivityState(); + connectivity_state_ = + subchannel()->CheckConnectivityState(&connected_subchannel_); return connectivity_state_; } @@ -135,8 +144,7 @@ class SubchannelData { private: // Watcher for subchannel connectivity state. - class Watcher - : public SubchannelInterface::ConnectivityStateWatcherInterface { + class Watcher : public SubchannelInterface::ConnectivityStateWatcher { public: Watcher( SubchannelData* subchannel_data, @@ -146,13 +154,42 @@ class SubchannelData { ~Watcher() { subchannel_list_.reset(DEBUG_LOCATION, "Watcher dtor"); } - void OnConnectivityStateChange(grpc_connectivity_state new_state) override; + void OnConnectivityStateChange(grpc_connectivity_state new_state, + RefCountedPtr + connected_subchannel) override; grpc_pollset_set* interested_parties() override { return subchannel_list_->policy()->interested_parties(); } private: + // A fire-and-forget class that bounces into the combiner to process + // a connectivity state update. + class Updater { + public: + Updater( + SubchannelData* + subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel); + + ~Updater() { + subchannel_list_.reset(DEBUG_LOCATION, "Watcher::Updater dtor"); + } + + private: + static void OnUpdateLocked(void* arg, grpc_error* error); + + SubchannelData* subchannel_data_; + RefCountedPtr> + subchannel_list_; + const grpc_connectivity_state state_; + RefCountedPtr connected_subchannel_; + grpc_closure closure_; + }; + SubchannelData* subchannel_data_; RefCountedPtr subchannel_list_; }; @@ -165,10 +202,10 @@ class SubchannelData { // The subchannel. RefCountedPtr subchannel_; // Will be non-null when the subchannel's state is being watched. - SubchannelInterface::ConnectivityStateWatcherInterface* pending_watcher_ = - nullptr; + SubchannelInterface::ConnectivityStateWatcher* pending_watcher_ = nullptr; // Data updated by the watcher. grpc_connectivity_state connectivity_state_; + RefCountedPtr connected_subchannel_; }; // A list of subchannels. @@ -195,6 +232,7 @@ class SubchannelList : public InternallyRefCounted { // the backoff code out of subchannels and into LB policies. void ResetBackoffLocked(); + // Note: Caller must ensure that this is invoked inside of the combiner. void Orphan() override { ShutdownLocked(); InternallyRefCounted::Unref(DEBUG_LOCATION, "shutdown"); @@ -204,7 +242,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, + const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args); @@ -225,6 +263,8 @@ class SubchannelList : public InternallyRefCounted { TraceFlag* tracer_; + grpc_combiner* combiner_; + // The list of subchannels. SubchannelVector subchannels_; @@ -244,26 +284,59 @@ class SubchannelList : public InternallyRefCounted { template void SubchannelData::Watcher:: - OnConnectivityStateChange(grpc_connectivity_state new_state) { - if (GRPC_TRACE_FLAG_ENABLED(*subchannel_list_->tracer())) { + OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr connected_subchannel) { + // Will delete itself. + New(subchannel_data_, + subchannel_list_->Ref(DEBUG_LOCATION, "Watcher::Updater"), + new_state, std::move(connected_subchannel)); +} + +template +SubchannelData::Watcher::Updater:: + Updater( + SubchannelData* subchannel_data, + RefCountedPtr> + subchannel_list, + grpc_connectivity_state state, + RefCountedPtr connected_subchannel) + : subchannel_data_(subchannel_data), + subchannel_list_(std::move(subchannel_list)), + state_(state), + connected_subchannel_(std::move(connected_subchannel)) { + GRPC_CLOSURE_INIT(&closure_, &OnUpdateLocked, this, + grpc_combiner_scheduler(subchannel_list_->combiner_)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); +} + +template +void SubchannelData::Watcher::Updater:: + OnUpdateLocked(void* arg, grpc_error* error) { + Updater* self = static_cast(arg); + SubchannelData* sd = self->subchannel_data_; + if (GRPC_TRACE_FLAG_ENABLED(*sd->subchannel_list_->tracer())) { gpr_log(GPR_INFO, "[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR " (subchannel %p): connectivity changed: state=%s, " - "shutting_down=%d, pending_watcher=%p", - subchannel_list_->tracer()->name(), subchannel_list_->policy(), - subchannel_list_.get(), subchannel_data_->Index(), - subchannel_list_->num_subchannels(), - subchannel_data_->subchannel_.get(), - grpc_connectivity_state_name(new_state), - subchannel_list_->shutting_down(), - subchannel_data_->pending_watcher_); + "connected_subchannel=%p, shutting_down=%d, pending_watcher=%p", + sd->subchannel_list_->tracer()->name(), + sd->subchannel_list_->policy(), sd->subchannel_list_, sd->Index(), + sd->subchannel_list_->num_subchannels(), sd->subchannel_.get(), + grpc_connectivity_state_name(self->state_), + self->connected_subchannel_.get(), + sd->subchannel_list_->shutting_down(), sd->pending_watcher_); } - if (!subchannel_list_->shutting_down() && - subchannel_data_->pending_watcher_ != nullptr) { - subchannel_data_->connectivity_state_ = new_state; + if (!sd->subchannel_list_->shutting_down() && + sd->pending_watcher_ != nullptr) { + sd->connectivity_state_ = self->state_; + // Get or release ref to connected subchannel. + sd->connected_subchannel_ = std::move(self->connected_subchannel_); // Call the subclass's ProcessConnectivityChangeLocked() method. - subchannel_data_->ProcessConnectivityChangeLocked(new_state); + sd->ProcessConnectivityChangeLocked(sd->connectivity_state_); } + // Clean up. + Delete(self); } // @@ -298,6 +371,7 @@ void SubchannelData:: subchannel_.get()); } subchannel_.reset(); + connected_subchannel_.reset(); } } @@ -326,7 +400,7 @@ void SubchannelData(this, subchannel_list()->Ref(DEBUG_LOCATION, "Watcher")); subchannel_->WatchConnectivityState( connectivity_state_, - UniquePtr( + UniquePtr( pending_watcher_)); } @@ -360,12 +434,13 @@ void SubchannelData::ShutdownLocked() { template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, - const ServerAddressList& addresses, + const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), - tracer_(tracer) { + tracer_(tracer), + combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels", @@ -434,6 +509,7 @@ SubchannelList::~SubchannelList() { gpr_log(GPR_INFO, "[%s %p] Destroying subchannel_list %p", tracer_->name(), policy_, this); } + GRPC_COMBINER_UNREF(combiner_, "subchannel_list"); } template diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 74660cec92b..e790ec25520 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -570,7 +570,7 @@ XdsLb::PickResult XdsLb::Picker::Pick(PickArgs args) { PickResult result = PickFromLocality(key, args); // If pick succeeded, add client stats. if (result.type == PickResult::PICK_COMPLETE && - result.subchannel != nullptr && client_stats_ != nullptr) { + result.connected_subchannel != nullptr && client_stats_ != nullptr) { // TODO(roth): Add support for client stats. } return result; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 99c7721e5e5..dd16eded826 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -86,7 +86,7 @@ ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, RefCountedPtr channelz_subchannel, intptr_t socket_uuid) - : RefCounted(&grpc_trace_subchannel_refcount), + : ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount), channel_stack_(channel_stack), args_(grpc_channel_args_copy(args)), channelz_subchannel_(std::move(channelz_subchannel)), @@ -378,12 +378,12 @@ class Subchannel::ConnectedSubchannelStateWatcher { // void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked( - OrphanablePtr watcher) { + UniquePtr watcher) { watchers_.insert(MakePair(watcher.get(), std::move(watcher))); } void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked( - ConnectivityStateWatcherInterface* watcher) { + ConnectivityStateWatcher* watcher) { watchers_.erase(watcher); } @@ -438,9 +438,8 @@ class Subchannel::HealthWatcherMap::HealthWatcher grpc_connectivity_state state() const { return state_; } - void AddWatcherLocked( - grpc_connectivity_state initial_state, - OrphanablePtr watcher) { + void AddWatcherLocked(grpc_connectivity_state initial_state, + UniquePtr watcher) { if (state_ != initial_state) { RefCountedPtr connected_subchannel; if (state_ == GRPC_CHANNEL_READY) { @@ -452,7 +451,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher watcher_list_.AddWatcherLocked(std::move(watcher)); } - void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher) { + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) { watcher_list_.RemoveWatcherLocked(watcher); } @@ -528,7 +527,7 @@ class Subchannel::HealthWatcherMap::HealthWatcher void Subchannel::HealthWatcherMap::AddWatcherLocked( Subchannel* subchannel, grpc_connectivity_state initial_state, UniquePtr health_check_service_name, - OrphanablePtr watcher) { + UniquePtr watcher) { // If the health check service name is not already present in the map, // add it. auto it = map_.find(health_check_service_name.get()); @@ -547,8 +546,7 @@ void Subchannel::HealthWatcherMap::AddWatcherLocked( } void Subchannel::HealthWatcherMap::RemoveWatcherLocked( - const char* health_check_service_name, - ConnectivityStateWatcherInterface* watcher) { + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { auto it = map_.find(health_check_service_name); GPR_ASSERT(it != map_.end()); it->second->RemoveWatcherLocked(watcher); @@ -820,7 +818,7 @@ grpc_connectivity_state Subchannel::CheckConnectivityState( void Subchannel::WatchConnectivityState( grpc_connectivity_state initial_state, UniquePtr health_check_service_name, - OrphanablePtr watcher) { + UniquePtr watcher) { MutexLock lock(&mu_); grpc_pollset_set* interested_parties = watcher->interested_parties(); if (interested_parties != nullptr) { @@ -839,8 +837,7 @@ void Subchannel::WatchConnectivityState( } void Subchannel::CancelConnectivityStateWatch( - const char* health_check_service_name, - ConnectivityStateWatcherInterface* watcher) { + const char* health_check_service_name, ConnectivityStateWatcher* watcher) { MutexLock lock(&mu_); grpc_pollset_set* interested_parties = watcher->interested_parties(); if (interested_parties != nullptr) { diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 9e8de767839..2f05792b872 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/subchannel_interface.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" @@ -69,7 +70,7 @@ namespace grpc_core { class SubchannelCall; -class ConnectedSubchannel : public RefCounted { +class ConnectedSubchannel : public ConnectedSubchannelInterface { public: struct CallArgs { grpc_polling_entity* pollent; @@ -96,7 +97,7 @@ class ConnectedSubchannel : public RefCounted { grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } - const grpc_channel_args* args() const { return args_; } + const grpc_channel_args* args() const override { return args_; } channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } @@ -175,35 +176,10 @@ class SubchannelCall { // A subchannel that knows how to connect to exactly one target address. It // provides a target for load balancing. -// -// Note that this is the "real" subchannel implementation, whose API is -// different from the SubchannelInterface that is exposed to LB policy -// implementations. The client channel provides an adaptor class -// (SubchannelWrapper) that "converts" between the two. class Subchannel { public: - class ConnectivityStateWatcherInterface - : public InternallyRefCounted { - public: - virtual ~ConnectivityStateWatcherInterface() = default; - - // Will be invoked whenever the subchannel's connectivity state - // changes. There will be only one invocation of this method on a - // given watcher instance at any given time. - // - // When the state changes to READY, connected_subchannel will - // contain a ref to the connected subchannel. When it changes from - // READY to some other state, the implementation must release its - // ref to the connected subchannel. - virtual void OnConnectivityStateChange( - grpc_connectivity_state new_state, - RefCountedPtr connected_subchannel) // NOLINT - GRPC_ABSTRACT; - - virtual grpc_pollset_set* interested_parties() GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS - }; + typedef SubchannelInterface::ConnectivityStateWatcher + ConnectivityStateWatcher; // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, @@ -230,8 +206,6 @@ class Subchannel { // Caller doesn't take ownership. const char* GetTargetAddress(); - const grpc_channel_args* channel_args() const { return args_; } - channelz::SubchannelNode* channelz_node(); // Returns the current connectivity state of the subchannel. @@ -251,15 +225,14 @@ class Subchannel { // changes. // The watcher will be destroyed either when the subchannel is // destroyed or when CancelConnectivityStateWatch() is called. - void WatchConnectivityState( - grpc_connectivity_state initial_state, - UniquePtr health_check_service_name, - OrphanablePtr watcher); + void WatchConnectivityState(grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); // Cancels a connectivity state watch. // If the watcher has already been destroyed, this is a no-op. void CancelConnectivityStateWatch(const char* health_check_service_name, - ConnectivityStateWatcherInterface* watcher); + ConnectivityStateWatcher* watcher); // Attempt to connect to the backend. Has no effect if already connected. void AttemptToConnect(); @@ -284,15 +257,14 @@ class Subchannel { grpc_resolved_address* addr); private: - // A linked list of ConnectivityStateWatcherInterfaces that are monitoring - // the subchannel's state. + // A linked list of ConnectivityStateWatchers that are monitoring the + // subchannel's state. class ConnectivityStateWatcherList { public: ~ConnectivityStateWatcherList() { Clear(); } - void AddWatcherLocked( - OrphanablePtr watcher); - void RemoveWatcherLocked(ConnectivityStateWatcherInterface* watcher); + void AddWatcherLocked(UniquePtr watcher); + void RemoveWatcherLocked(ConnectivityStateWatcher* watcher); // Notifies all watchers in the list about a change to state. void NotifyLocked(Subchannel* subchannel, grpc_connectivity_state state); @@ -304,13 +276,12 @@ class Subchannel { private: // TODO(roth): This could be a set instead of a map if we had a set // implementation. - Map> + Map> watchers_; }; - // A map that tracks ConnectivityStateWatcherInterfaces using a particular - // health check service name. + // A map that tracks ConnectivityStateWatchers using a particular health + // check service name. // // There is one entry in the map for each health check service name. // Entries exist only as long as there are watchers using the @@ -320,12 +291,12 @@ class Subchannel { // state READY. class HealthWatcherMap { public: - void AddWatcherLocked( - Subchannel* subchannel, grpc_connectivity_state initial_state, - UniquePtr health_check_service_name, - OrphanablePtr watcher); + void AddWatcherLocked(Subchannel* subchannel, + grpc_connectivity_state initial_state, + UniquePtr health_check_service_name, + UniquePtr watcher); void RemoveWatcherLocked(const char* health_check_service_name, - ConnectivityStateWatcherInterface* watcher); + ConnectivityStateWatcher* watcher); // Notifies the watcher when the subchannel's state changes. void NotifyLocked(grpc_connectivity_state state); diff --git a/src/core/ext/filters/client_channel/subchannel_interface.h b/src/core/ext/filters/client_channel/subchannel_interface.h index 2e448dc5a64..10b1bf124c2 100644 --- a/src/core/ext/filters/client_channel/subchannel_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_interface.h @@ -21,22 +21,42 @@ #include +#include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { -// The interface for subchannels that is exposed to LB policy implementations. +// TODO(roth): In a subsequent PR, remove this from this API. +class ConnectedSubchannelInterface + : public RefCounted { + public: + virtual const grpc_channel_args* args() const GRPC_ABSTRACT; + + protected: + template + explicit ConnectedSubchannelInterface(TraceFlagT* trace_flag = nullptr) + : RefCounted(trace_flag) {} +}; + class SubchannelInterface : public RefCounted { public: - class ConnectivityStateWatcherInterface { + class ConnectivityStateWatcher { public: - virtual ~ConnectivityStateWatcherInterface() = default; + virtual ~ConnectivityStateWatcher() = default; // Will be invoked whenever the subchannel's connectivity state // changes. There will be only one invocation of this method on a // given watcher instance at any given time. - virtual void OnConnectivityStateChange(grpc_connectivity_state new_state) + // + // When the state changes to READY, connected_subchannel will + // contain a ref to the connected subchannel. When it changes from + // READY to some other state, the implementation must release its + // ref to the connected subchannel. + virtual void OnConnectivityStateChange( + grpc_connectivity_state new_state, + RefCountedPtr + connected_subchannel) // NOLINT GRPC_ABSTRACT; // TODO(roth): Remove this as soon as we move to EventManager-based @@ -46,14 +66,12 @@ class SubchannelInterface : public RefCounted { GRPC_ABSTRACT_BASE_CLASS }; - template - explicit SubchannelInterface(TraceFlagT* trace_flag = nullptr) - : RefCounted(trace_flag) {} - virtual ~SubchannelInterface() = default; // Returns the current connectivity state of the subchannel. - virtual grpc_connectivity_state CheckConnectivityState() GRPC_ABSTRACT; + virtual grpc_connectivity_state CheckConnectivityState( + RefCountedPtr* connected_subchannel) + GRPC_ABSTRACT; // Starts watching the subchannel's connectivity state. // The first callback to the watcher will be delivered when the @@ -68,12 +86,12 @@ class SubchannelInterface : public RefCounted { // the previous watcher using CancelConnectivityStateWatch(). virtual void WatchConnectivityState( grpc_connectivity_state initial_state, - UniquePtr watcher) GRPC_ABSTRACT; + UniquePtr watcher) GRPC_ABSTRACT; // Cancels a connectivity state watch. // If the watcher has already been destroyed, this is a no-op. - virtual void CancelConnectivityStateWatch( - ConnectivityStateWatcherInterface* watcher) GRPC_ABSTRACT; + virtual void CancelConnectivityStateWatch(ConnectivityStateWatcher* watcher) + GRPC_ABSTRACT; // Attempt to connect to the backend. Has no effect if already connected. // If the subchannel is currently in backoff delay due to a previously @@ -87,9 +105,6 @@ class SubchannelInterface : public RefCounted { // attempt will be started as soon as AttemptToConnect() is called. virtual void ResetBackoff() GRPC_ABSTRACT; - // TODO(roth): Need a better non-grpc-specific abstraction here. - virtual const grpc_channel_args* channel_args() GRPC_ABSTRACT; - GRPC_ABSTRACT_BASE_CLASS }; diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h index 566691df580..36e32d60c07 100644 --- a/src/core/lib/gprpp/map.h +++ b/src/core/lib/gprpp/map.h @@ -30,7 +30,6 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/pair.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" namespace grpc_core { struct StringLess { @@ -42,13 +41,6 @@ struct StringLess { } }; -template -struct RefCountedPtrLess { - bool operator()(const RefCountedPtr& p1, const RefCountedPtr& p2) { - return p1.get() < p2.get(); - } -}; - namespace testing { class MapTest; } @@ -63,28 +55,8 @@ class Map { typedef Compare key_compare; class iterator; - Map() {} ~Map() { clear(); } - // Copying not currently supported. - Map(const Map& other) = delete; - - // Move support. - Map(Map&& other) : root_(other.root_), size_(other.size_) { - other.root_ = nullptr; - other.size_ = 0; - } - Map& operator=(Map&& other) { - if (this != &other) { - clear(); - root_ = other.root_; - size_ = other.size_; - other.root_ = nullptr; - other.size_ = 0; - } - return *this; - } - T& operator[](key_type&& key); T& operator[](const key_type& key); iterator find(const key_type& k); diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 7766ee186c6..1523ced16d8 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -222,12 +222,7 @@ void grpc_mdctx_global_shutdown() { abort(); } } - // For ASAN builds, we don't want to crash here, because that will - // prevent ASAN from providing leak detection information, which is - // far more useful than this simple assertion. -#ifndef GRPC_ASAN_ENABLED GPR_DEBUG_ASSERT(shard->count == 0); -#endif gpr_free(shard->elems); } } diff --git a/test/core/gprpp/map_test.cc b/test/core/gprpp/map_test.cc index 21aeee82486..30d9eb0b207 100644 --- a/test/core/gprpp/map_test.cc +++ b/test/core/gprpp/map_test.cc @@ -437,35 +437,6 @@ TEST_F(MapTest, LowerBound) { EXPECT_EQ(it, test_map.end()); } -// Test move ctor -TEST_F(MapTest, MoveCtor) { - Map test_map; - for (int i = 0; i < 5; i++) { - test_map.emplace(kKeys[i], Payload(i)); - } - Map test_map2 = std::move(test_map); - for (int i = 0; i < 5; i++) { - EXPECT_EQ(test_map.end(), test_map.find(kKeys[i])); - EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data()); - } -} - -// Test move assignment -TEST_F(MapTest, MoveAssignment) { - Map test_map; - for (int i = 0; i < 5; i++) { - test_map.emplace(kKeys[i], Payload(i)); - } - Map test_map2; - test_map2.emplace("xxx", Payload(123)); - test_map2 = std::move(test_map); - for (int i = 0; i < 5; i++) { - EXPECT_EQ(test_map.end(), test_map.find(kKeys[i])); - EXPECT_EQ(i, test_map2.find(kKeys[i])->second.data()); - } - EXPECT_EQ(test_map2.end(), test_map2.find("xxx")); -} - } // namespace testing } // namespace grpc_core diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 041ce1f45a1..2c1f988d173 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -117,7 +117,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy PickResult Pick(PickArgs args) override { PickResult result = delegate_picker_->Pick(args); if (result.type == PickResult::PICK_COMPLETE && - result.subchannel != nullptr) { + result.connected_subchannel != nullptr) { new (args.call_state->Alloc(sizeof(TrailingMetadataHandler))) TrailingMetadataHandler(&result, cb_, user_data_); } From 662aa1f153853399bcface2928f3230e71f5fc61 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 18 Jun 2019 10:53:53 -0700 Subject: [PATCH 371/676] Modify format printing and Debug trace. --- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 44 ++++++++++--------- src/core/lib/iomgr/threadpool/mpmcqueue.h | 49 ++++++++++------------ 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index b2e09b9c81b..64f7d19a2a7 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -16,21 +16,24 @@ * */ -#include - #include "src/core/lib/iomgr/threadpool/mpmcqueue.h" #include #include #include +#include #include #include +#include #include +#include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/sync.h" namespace grpc_core { +DebugOnlyTraceFlag thread_pool_trace(false, "thread_pool_trace"); + inline void* MPMCQueue::PopFront() { void* result = queue_head_->content; Node* head_to_remove = queue_head_; @@ -55,6 +58,10 @@ inline void* MPMCQueue::PopFront() { gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); } + if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { + PrintStats(); + } + // Singal waiting thread if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) { wait_nonempty_.Signal(); @@ -70,10 +77,11 @@ MPMCQueue::MPMCQueue() MPMCQueue::~MPMCQueue() { GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); - ReleasableMutexLock l(&mu_); + MutexLock l(&mu_); GPR_ASSERT(num_waiters_ == 0); - l.Unlock(); - PrintStats(); + if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { + PrintStats(); + } } void MPMCQueue::Put(void* elem) { @@ -91,6 +99,9 @@ void MPMCQueue::Put(void* elem) { // Update Stats info stats_.num_started++; + if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { + PrintStats(); + } if (num_waiters_ > 0) { wait_nonempty_.Signal(); @@ -111,28 +122,15 @@ void* MPMCQueue::Get() { } void MPMCQueue::PrintStats() { - MutexLock l(&mu_); gpr_log(GPR_INFO, "STATS INFO:"); - gpr_log(GPR_INFO, "num_started: %lu", stats_.num_started); - gpr_log(GPR_INFO, "num_completed: %lu", stats_.num_completed); - gpr_log(GPR_INFO, "total_queue_cycles: %d", + gpr_log(GPR_INFO, "num_started: %" PRIu64, stats_.num_started); + gpr_log(GPR_INFO, "num_completed: %" PRIu64, stats_.num_completed); + gpr_log(GPR_INFO, "total_queue_cycles: %" PRId32, gpr_time_to_millis(stats_.total_queue_cycles)); - gpr_log(GPR_INFO, "max_queue_cycles: %d", + gpr_log(GPR_INFO, "max_queue_cycles: %" PRId32, gpr_time_to_millis(stats_.max_queue_cycles)); - gpr_log(GPR_INFO, "busy_time_cycles: %d", + gpr_log(GPR_INFO, "busy_time_cycles: %" PRId32, gpr_time_to_millis(stats_.busy_time_cycles)); } -MPMCQueue::Stats* MPMCQueue::queue_stats() { - MPMCQueue::Stats* result = new Stats(); - MutexLock l(&mu_); - result->total_queue_cycles = - gpr_time_add(result->total_queue_cycles, stats_.total_queue_cycles); - result->max_queue_cycles = - gpr_time_add(result->max_queue_cycles, stats_.max_queue_cycles); - result->busy_time_cycles = - gpr_time_add(result->busy_time_cycles, stats_.busy_time_cycles); - return result; -} - } // namespace grpc_core diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h index 8c8395e1d9d..b39c9d81f4f 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -48,25 +48,6 @@ class MPMCQueueInterface { class MPMCQueue : public MPMCQueueInterface { public: - struct Stats { // Stats of queue - uint64_t num_started; // Number of elements have been added to queue - uint64_t num_completed; // Number of elements have been removed from - // the queue - gpr_timespec total_queue_cycles; // Total waiting time that all the - // removed elements have spent in queue - gpr_timespec max_queue_cycles; // Max waiting time among all removed - // elements - gpr_timespec busy_time_cycles; // Accumulated amount of time that queue - // was not empty - - Stats() { - num_started = 0; - num_completed = 0; - total_queue_cycles = gpr_time_0(GPR_TIMESPAN); - max_queue_cycles = gpr_time_0(GPR_TIMESPAN); - busy_time_cycles = gpr_time_0(GPR_TIMESPAN); - } - }; // Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created // will have infinite length. explicit MPMCQueue(); @@ -88,16 +69,12 @@ class MPMCQueue : public MPMCQueueInterface { // quickly. int count() const { return count_.Load(MemoryOrder::RELAXED); } - // Print out Stats. Time measurement are printed in millisecond. - void PrintStats(); - - // Return a copy of current stats info. This info will be changed quickly - // when queue is still running. This copy will not deleted by queue. - Stats* queue_stats(); - private: void* PopFront(); + // Print out Stats. Time measurement are printed in millisecond. + void PrintStats(); + struct Node { Node* next; // Linking void* content; // Points to actual element @@ -109,6 +86,26 @@ class MPMCQueue : public MPMCQueueInterface { } }; + struct Stats { // Stats of queue + uint64_t num_started; // Number of elements have been added to queue + uint64_t num_completed; // Number of elements have been removed from + // the queue + gpr_timespec total_queue_cycles; // Total waiting time that all the + // removed elements have spent in queue + gpr_timespec max_queue_cycles; // Max waiting time among all removed + // elements + gpr_timespec busy_time_cycles; // Accumulated amount of time that queue + // was not empty + + Stats() { + num_started = 0; + num_completed = 0; + total_queue_cycles = gpr_time_0(GPR_TIMESPAN); + max_queue_cycles = gpr_time_0(GPR_TIMESPAN); + busy_time_cycles = gpr_time_0(GPR_TIMESPAN); + } + }; + Mutex mu_; // Protecting lock CondVar wait_nonempty_; // Wait on empty queue on get int num_waiters_; // Number of waiters From 9b49f03cf7a28886ff4b1dcacfd2861d6e3f5364 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 18 Jun 2019 11:03:43 -0700 Subject: [PATCH 372/676] Relax deadline check in c# --- src/csharp/Grpc.Core.Tests/TimeoutsTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs index b89c1afcc35..55e69a01813 100644 --- a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs +++ b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs @@ -80,7 +80,7 @@ namespace Grpc.Core.Tests // A fairly relaxed check that the deadline set by client and deadline seen by server // are in agreement. C core takes care of the work with transferring deadline over the wire, // so we don't need an exact check here. - Assert.IsTrue(Math.Abs((clientDeadline - context.Deadline).TotalMilliseconds) < 5000); + Assert.IsTrue(Math.Abs((clientDeadline - context.Deadline).TotalHours) < 1); return Task.FromResult("PASS"); }); Calls.BlockingUnaryCall(helper.CreateUnaryCall(new CallOptions(deadline: clientDeadline)), "abc"); From ce856d27f4c25b213250b9577b4a0dd3467a8567 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 18 Jun 2019 11:16:24 -0700 Subject: [PATCH 373/676] Add extern declaration and adjust header --- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 8 +++++--- src/core/lib/iomgr/threadpool/mpmcqueue.h | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index 64f7d19a2a7..a59d62e5750 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -18,14 +18,16 @@ #include "src/core/lib/iomgr/threadpool/mpmcqueue.h" +#include + +#include +#include + #include #include #include -#include #include #include -#include -#include #include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/sync.h" diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/threadpool/mpmcqueue.h index b39c9d81f4f..2d77a281c5b 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.h @@ -24,11 +24,14 @@ #include #include +#include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/sync.h" namespace grpc_core { +extern DebugOnlyTraceFlag thread_pool_trace; + // Abstract base class of a MPMC queue interface class MPMCQueueInterface { public: From 917605735b99a3e367bde88875131532d063122c Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 18 Jun 2019 11:23:10 -0700 Subject: [PATCH 374/676] Adjust port header position --- src/core/lib/iomgr/threadpool/mpmcqueue.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/threadpool/mpmcqueue.cc index a59d62e5750..f39abe572c0 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/threadpool/mpmcqueue.cc @@ -16,10 +16,10 @@ * */ -#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" - #include +#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" + #include #include From 9640bcddc24f9ec32e3ec967ca83986cf35814bf Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Jun 2019 14:17:15 -0700 Subject: [PATCH 375/676] fix testHijackingInterceptor --- src/objective-c/tests/InteropTests/InteropTests.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 235fcaed483..5587e78bfae 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -1497,8 +1497,10 @@ static dispatch_once_t initGlobalInterceptorFactory; - (void)testHijackingInterceptor { NSUInteger kCancelAfterWrites = 2; XCTAssertNotNil([[self class] host]); - __weak XCTestExpectation *expectation = - [self expectationWithDescription:@"testHijackingInterceptor"]; + __weak XCTestExpectation *expectUserCallComplete = + [self expectationWithDescription:@"User call completed."]; + __weak XCTestExpectation *expectCallInternalComplete = + [self expectationWithDescription:@"Internal gRPC call completed."]; NSArray *responses = @[ @1, @2, @3, @4 ]; __block int index = 0; @@ -1555,6 +1557,7 @@ static dispatch_once_t initGlobalInterceptorFactory; XCTAssertNil(trailingMetadata); XCTAssertNotNil(error); XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); + [expectCallInternalComplete fulfill]; } didWriteDataHook:nil]; @@ -1596,7 +1599,7 @@ static dispatch_once_t initGlobalInterceptorFactory; XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index); - [expectation fulfill]; + [expectUserCallComplete fulfill]; }] callOptions:options]; [call start]; From ad61ae12359a0c493170499220e89530e6185c10 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 18 Jun 2019 14:23:06 -0700 Subject: [PATCH 376/676] clang-format --- .../GRPCClient/GRPCCall+Interceptor.m | 5 +- src/objective-c/GRPCClient/GRPCCall.m | 5 +- .../tests/InteropTests/InteropTests.m | 89 +++++++++---------- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+Interceptor.m b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m index eed402f9c7e..0d9f1f6b9dc 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Interceptor.m +++ b/src/objective-c/GRPCClient/GRPCCall+Interceptor.m @@ -35,7 +35,10 @@ static dispatch_once_t onceToken; [globalInterceptorLock lock]; if (globalInterceptorFactory != nil) { [globalInterceptorLock unlock]; - [NSException raise:NSInternalInconsistencyException format:@"Global interceptor is already registered. Only one global interceptor can be registered in a process."]; + [NSException raise:NSInternalInconsistencyException + format: + @"Global interceptor is already registered. Only one global interceptor can be " + @"registered in a process."]; return; } diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c25e8daaf4c..d5f4e9a84da 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -166,9 +166,8 @@ const char *kCFStreamVarName = "grpc_cfstream"; NSArray *interceptorFactories = _actualCallOptions.interceptorFactories; for (int i = (int)interceptorFactories.count - 1; i >= 0; i--) { GRPCInterceptorManager *manager = - [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; - GRPCInterceptor *interceptor = - [interceptorFactories[i] createInterceptorWithManager:manager]; + [[GRPCInterceptorManager alloc] initWithNextInterceptor:nextInterceptor]; + GRPCInterceptor *interceptor = [interceptorFactories[i] createInterceptorWithManager:manager]; NSAssert(interceptor != nil, @"Failed to create interceptor from factory: %@", interceptorFactories[i]); if (interceptor == nil) { diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 5587e78bfae..d8dc3f6c32d 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -144,7 +144,7 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager @end @implementation HookInterceptorFactory { -@protected + @protected void (^_startHook)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager); void (^_writeDataHook)(id data, GRPCInterceptorManager *manager); @@ -323,19 +323,18 @@ initWithInterceptorManager:(GRPCInterceptorManager *)interceptorManager - (instancetype)initWithRequestDispatchQueue:(dispatch_queue_t)requestDispatchQueue responseDispatchQueue:(dispatch_queue_t)responseDispatchQueue; -- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, - GRPCCallOptions *callOptions, +- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook -receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, - GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, - GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, - GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook; @end @@ -374,19 +373,18 @@ receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, } } -- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, - GRPCCallOptions *callOptions, +- (void)setStartHook:(void (^)(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, GRPCInterceptorManager *manager))startHook - writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook - finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook -receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, - GRPCInterceptorManager *manager))receiveNextMessagesHook - responseHeaderHook:(void (^)(NSDictionary *initialMetadata, - GRPCInterceptorManager *manager))responseHeaderHook - responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook - responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, - GRPCInterceptorManager *manager))responseCloseHook - didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { + writeDataHook:(void (^)(id data, GRPCInterceptorManager *manager))writeDataHook + finishHook:(void (^)(GRPCInterceptorManager *manager))finishHook + receiveNextMessagesHook:(void (^)(NSUInteger numberOfMessages, + GRPCInterceptorManager *manager))receiveNextMessagesHook + responseHeaderHook:(void (^)(NSDictionary *initialMetadata, + GRPCInterceptorManager *manager))responseHeaderHook + responseDataHook:(void (^)(id data, GRPCInterceptorManager *manager))responseDataHook + responseCloseHook:(void (^)(NSDictionary *trailingMetadata, NSError *error, + GRPCInterceptorManager *manager))responseCloseHook + didWriteDataHook:(void (^)(GRPCInterceptorManager *manager))didWriteDataHook { _startHook = startHook; _writeDataHook = writeDataHook; _finishHook = finishHook; @@ -448,8 +446,9 @@ static dispatch_once_t initGlobalInterceptorFactory; dispatch_once(&initGlobalInterceptorFactory, ^{ dispatch_queue_t globalInterceptorQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); - globalInterceptorFactory = [[GlobalInterceptorFactory alloc] initWithRequestDispatchQueue:globalInterceptorQueue - responseDispatchQueue:globalInterceptorQueue]; + globalInterceptorFactory = + [[GlobalInterceptorFactory alloc] initWithRequestDispatchQueue:globalInterceptorQueue + responseDispatchQueue:globalInterceptorQueue]; [GRPCCall2 registerGlobalInterceptor:globalInterceptorFactory]; }); } @@ -1628,15 +1627,15 @@ static dispatch_once_t initGlobalInterceptorFactory; __block NSUInteger responseDataCount = 0; __block NSUInteger responseCloseCount = 0; __block NSUInteger didWriteDataCount = 0; - [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, - GRPCInterceptorManager *manager) { - startCount++; - XCTAssertEqualObjects(requestOptions.host, [[self class] host]); - XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); - XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); - [manager startNextInterceptorWithRequest:[requestOptions copy] - callOptions:[callOptions copy]]; - } + [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + startCount++; + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; + } writeDataHook:^(id data, GRPCInterceptorManager *manager) { writeDataCount++; [manager writeNextInterceptorWithData:data]; @@ -1813,15 +1812,15 @@ static dispatch_once_t initGlobalInterceptorFactory; __block NSUInteger globalResponseCloseCount = 0; __block NSUInteger globalDidWriteDataCount = 0; - [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, GRPCCallOptions *callOptions, - GRPCInterceptorManager *manager) { - globalStartCount++; - XCTAssertEqualObjects(requestOptions.host, [[self class] host]); - XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); - XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); - [manager startNextInterceptorWithRequest:[requestOptions copy] - callOptions:[callOptions copy]]; - } + [globalInterceptorFactory setStartHook:^(GRPCRequestOptions *requestOptions, + GRPCCallOptions *callOptions, + GRPCInterceptorManager *manager) { + globalStartCount++; + XCTAssertEqualObjects(requestOptions.host, [[self class] host]); + XCTAssertEqualObjects(requestOptions.path, @"/grpc.testing.TestService/FullDuplexCall"); + XCTAssertEqual(requestOptions.safety, GRPCCallSafetyDefault); + [manager startNextInterceptorWithRequest:[requestOptions copy] callOptions:[callOptions copy]]; + } writeDataHook:^(id data, GRPCInterceptorManager *manager) { globalWriteDataCount++; [manager writeNextInterceptorWithData:data]; From 63ffdf135fcd1a3cb9cbfb8751dbc05a62b8e390 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 18 Jun 2019 15:40:19 -0700 Subject: [PATCH 377/676] Bump version to 1.23.0 --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index 108b0f79b94..8fd52808400 100644 --- a/BUILD +++ b/BUILD @@ -74,11 +74,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "gale" +g_stands_for = "gangnam" core_version = "7.0.0" -version = "1.22.0-dev" +version = "1.23.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index bb53d6693fe..dad2146bd1c 100644 --- a/build.yaml +++ b/build.yaml @@ -13,8 +13,8 @@ settings: '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 - g_stands_for: gale - version: 1.22.0-dev + g_stands_for: gangnam + version: 1.23.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 90202b1b880..fe1cbc90005 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -21,4 +21,5 @@ - 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) - 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) - 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x) -- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/master) +- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/v1.22.x) +- 1.23 'g' stands for ['gangnam'](https://github.com/grpc/grpc/tree/master) From cd27a369245723d8e3c75f1a9e6129a4f8ad2abd Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 18 Jun 2019 15:40:50 -0700 Subject: [PATCH 378/676] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 4 ++-- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 31 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d54ec0cda..12998e1727f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.22.0-dev") +set(PACKAGE_VERSION "1.23.0-dev") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index d45c0992370..f2ef973a42e 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.22.0-dev -CSHARP_VERSION = 1.22.0-dev +CPP_VERSION = 1.23.0-dev +CSHARP_VERSION = 1.23.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 18ed5f89102..f0a4418b20c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.22.0-dev' + # version = '1.23.0-dev' version = '0.0.9-dev' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.22.0-dev' + grpc_version = '1.23.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 85add8fb7a2..2e34e8d7573 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.22.0-dev' + version = '1.23.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 1cac59c6cc4..2c0441ba95c 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.22.0-dev' + version = '1.23.0-dev' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 6f033ea71b7..12a8728ac34 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.22.0-dev' + version = '1.23.0-dev' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index e9c3fd7bee0..bbfd08f9774 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.22.0-dev' + version = '1.23.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index fd712698a62..616e1ece20e 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.22.0dev - 1.22.0dev + 1.23.0dev + 1.23.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 7d9d49bc2aa..848a49d1eff 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "7.0.0"; } -const char* grpc_g_stands_for(void) { return "gale"; } +const char* grpc_g_stands_for(void) { return "gangnam"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 76e2773e938..7fb7823c9f2 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.22.0-dev"; } +grpc::string Version() { return "1.23.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index fb67fe622b5..6469aeb3f4b 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.22.0.0"; + public const string CurrentAssemblyFileVersion = "1.23.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.22.0-dev"; + public const string CurrentVersion = "1.23.0-dev"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index dd5f172c27b..d9bf90ff007 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.22.0-dev + 1.23.0-dev 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 2f4cd2739da..4211d70b235 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.22.0-dev +set VERSION=1.23.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 401540209af..e9b5645d012 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.22.0-dev' + v = '1.23.0-dev' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 6fe0c396dd3..3b248db0148 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.23.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index c835c1da190..231ba1a9a9f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.23.0-dev" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index ca1001b6d2b..e29c9c33fde 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.22.0", + "version": "1.23.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 3e9f88c61d6..bb707f50a9f 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.22.0dev" +#define PHP_GRPC_VERSION "1.23.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 9f7ca9d5603..d2f8be43f34 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.22.0.dev0""" +__version__ = """1.23.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 971fd37afb6..548d2810b5b 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 52baab4c30f..f7029fff484 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index be4ca841361..d66daa473ed 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 1efc4ee2c8d..97213872a91 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 9e443087755..31921b4cc90 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 18d17e40464..5c8926cb6c8 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 401b0bd9697..a1fc87448a1 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 75e6191216d..051bc067e55 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.22.0.dev' + VERSION = '1.23.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index fbd0041fa35..e66a4a799fd 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.22.0.dev' + VERSION = '1.23.0.dev' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 24ec4301b65..127d3c1f9bc 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.23.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 466bb5cd5a3..183ab0dff53 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.22.0-dev +PROJECT_NUMBER = 1.23.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 9b0f8f9fcd7..e2d753e02eb 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.22.0-dev +PROJECT_NUMBER = 1.23.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 26769ae50fa0a29b3179f810ea3bbb1b9088766f Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 18 Jun 2019 15:43:54 -0700 Subject: [PATCH 379/676] Bump version to v1.22.0-pre1 --- BUILD | 2 +- build.yaml | 2 +- doc/g_stands_for.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD b/BUILD index 108b0f79b94..0ca0d9b7fd8 100644 --- a/BUILD +++ b/BUILD @@ -78,7 +78,7 @@ g_stands_for = "gale" core_version = "7.0.0" -version = "1.22.0-dev" +version = "1.22.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index bb53d6693fe..cce7d1bbe5c 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gale - version: 1.22.0-dev + version: 1.22.0-pre1 filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 90202b1b880..6acee77cf5d 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -21,4 +21,4 @@ - 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) - 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/v1.20.x) - 1.21 'g' stands for ['gandalf'](https://github.com/grpc/grpc/tree/v1.21.x) -- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/master) +- 1.22 'g' stands for ['gale'](https://github.com/grpc/grpc/tree/v1.22.x) From ebfd812be149d325967c5b49ca4f2a7d1bb8a108 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Tue, 18 Jun 2019 15:44:33 -0700 Subject: [PATCH 380/676] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core.Api/VersionInfo.cs | 2 +- src/csharp/build/dependencies.props | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 33 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d54ec0cda..76f19024f0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.22.0-dev") +set(PACKAGE_VERSION "1.22.0-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index d45c0992370..0b1a9259d91 100644 --- a/Makefile +++ b/Makefile @@ -460,8 +460,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.22.0-dev -CSHARP_VERSION = 1.22.0-dev +CPP_VERSION = 1.22.0-pre1 +CSHARP_VERSION = 1.22.0-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 18ed5f89102..4cdf65fcc99 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.22.0-dev' - version = '0.0.9-dev' + # version = '1.22.0-pre1' + version = '0.0.9-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.22.0-dev' + grpc_version = '1.22.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 85add8fb7a2..a40c9511fd2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.22.0-dev' + version = '1.22.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 1cac59c6cc4..00609603438 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.22.0-dev' + version = '1.22.0-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 6f033ea71b7..b3423e97791 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.22.0-dev' + version = '1.22.0-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index e9c3fd7bee0..7b13447ff3f 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.22.0-dev' + version = '1.22.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index fd712698a62..01ed99d0f91 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.22.0dev - 1.22.0dev + 1.22.0RC1 + 1.22.0RC1 beta diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 76e2773e938..ebd4f7ef023 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.22.0-dev"; } +grpc::string Version() { return "1.22.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core.Api/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs index fb67fe622b5..a9b73c24c27 100644 --- a/src/csharp/Grpc.Core.Api/VersionInfo.cs +++ b/src/csharp/Grpc.Core.Api/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.22.0-dev"; + public const string CurrentVersion = "1.22.0-pre1"; } } diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index dd5f172c27b..662ac407713 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -1,7 +1,7 @@ - 1.22.0-dev + 1.22.0-pre1 3.7.0 diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 2f4cd2739da..b2f855e10e7 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.22.0-dev +set VERSION=1.22.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 401540209af..37160fbd3fb 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.22.0-dev' + v = '1.22.0-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 6fe0c396dd3..05829ac102c 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index c835c1da190..68ea0849659 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.22.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.22.0-pre1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 3e9f88c61d6..4ebb30d2ff5 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.22.0dev" +#define PHP_GRPC_VERSION "1.22.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 9f7ca9d5603..fa594107fec 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.22.0.dev0""" +__version__ = """1.22.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 971fd37afb6..e878336b40c 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 52baab4c30f..edd2b36e5d3 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index be4ca841361..44b59737fd9 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 1efc4ee2c8d..02fc7b80423 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 9e443087755..0b70be2fd4b 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 18d17e40464..21c75d294e8 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 401b0bd9697..2bb40b514a6 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 75e6191216d..5e6d6de685a 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.22.0.dev' + VERSION = '1.22.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index fbd0041fa35..e86c6330a70 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.22.0.dev' + VERSION = '1.22.0.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 24ec4301b65..810493f00da 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.22.0.dev0' +VERSION = '1.22.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 466bb5cd5a3..2de0dbb9af7 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.22.0-dev +PROJECT_NUMBER = 1.22.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 9b0f8f9fcd7..ba8a287104a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.22.0-dev +PROJECT_NUMBER = 1.22.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 02813afa65fab0f00209e65a4f687f5bc7712adc Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 18 Jun 2019 16:32:31 -0700 Subject: [PATCH 381/676] Extend thread class to accept setting stack size as a option --- src/core/lib/gprpp/thd.h | 12 +++++++++++- src/core/lib/gprpp/thd_posix.cc | 22 ++++++++++++++++++++++ src/core/lib/gprpp/thd_windows.cc | 10 +++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index cae707061e0..6f29f82427f 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -49,7 +49,7 @@ class Thread { public: class Options { public: - Options() : joinable_(true), tracked_(true) {} + Options() : joinable_(true), tracked_(true), stack_size_(0) {} /// Set whether the thread is joinable or detached. Options& set_joinable(bool joinable) { joinable_ = joinable; @@ -64,9 +64,19 @@ class Thread { } bool tracked() const { return tracked_; } + /// Set thread stack size (in bytes). Set to 0 will reset stack size to + /// default value, which is 64KB for Windows threads and 2MB for Posix(x86) + /// threads. + Options& set_stack_size(size_t bytes) { + stack_size_ = bytes; + return *this; + } + size_t stack_size() const { return stack_size_; } + private: bool joinable_; bool tracked_; + size_t stack_size_; }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 28932081538..5d202013b1d 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/fork.h" @@ -48,6 +49,22 @@ struct thd_arg { bool tracked; }; +size_t RoundUpToPageSize(size_t size) { + size_t page_size = static_cast(getpagesize()); + return (size + page_size - 1) & ~(page_size - 1); +} + +// Return the minimum valid stack size that can be passed to +// pthread_attr_setstacksize. +size_t MinValidStackSize(size_t request_size) { + if (request_size < _SC_THREAD_STACK_MIN) + request_size = _SC_THREAD_STACK_MIN; + + // On some systems, pthread_attr_setstacksize() can fail if stacksize is + // not a multiple of the system page size. + return RoundUpToPageSize(request_size); +} + class ThreadInternalsPosix : public internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), @@ -79,6 +96,11 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { 0); } + if (options.stack_size() != 0) { + size_t stack_size = MinValidStackSize(options.stack_size()); + GPR_ASSERT(pthread_attr_setstacksize(&attr, stack_size) == 0); + } + *success = (pthread_create(&pthread_id_, &attr, [](void* v) -> void* { diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index bbb48a58cd6..5014444dcfd 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -75,7 +75,15 @@ class ThreadInternalsWindows return; } } - handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); + + if (options.stack_size() != 0) { + // Windows will round up the given stack_size value to nearest page. + handle = CreateThread(nullptr, options.stack_size(), thread_body, info_, + 0, nullptr); + } else { + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); + } + if (handle == nullptr) { destroy_thread(); *success = false; From 17d74286c7b793e9a9e9bc705f92605783de8ce3 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 18 Jun 2019 17:19:26 -0700 Subject: [PATCH 382/676] clang-format --- src/core/lib/gprpp/thd_posix.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 5d202013b1d..965a3ba229a 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -57,8 +57,9 @@ size_t RoundUpToPageSize(size_t size) { // Return the minimum valid stack size that can be passed to // pthread_attr_setstacksize. size_t MinValidStackSize(size_t request_size) { - if (request_size < _SC_THREAD_STACK_MIN) + if (request_size < _SC_THREAD_STACK_MIN) { request_size = _SC_THREAD_STACK_MIN; + } // On some systems, pthread_attr_setstacksize() can fail if stacksize is // not a multiple of the system page size. From afe91a47f7bb4366f8fe187fa83d12dab9300f57 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 09:48:45 -0700 Subject: [PATCH 383/676] Update Protobuf version --- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/!ProtoCompiler.podspec | 2 +- .../src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 37160fbd3fb..2769bb3e4e3 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -101,7 +101,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 58d74be4d4e..d8ce4d8e89d 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.7.0' + v = '3.8.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 741f9b7e54d..b2335ac8a9e 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -103,7 +103,7 @@ s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' From 7a22143d7ab5f52620ab3ef2377b6090d1a8a3f7 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 19 Jun 2019 09:54:50 -0700 Subject: [PATCH 384/676] Run callbacks on same thread if trigerred from background thread --- src/core/lib/surface/completion_queue.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 60a7d78b525..55bfb6fcc30 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -857,17 +857,20 @@ static void cq_end_op_for_callback( } auto* functor = static_cast(tag); - if (internal) { + if (internal || grpc_iomgr_is_any_background_poller_thread()) { grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, (error == GRPC_ERROR_NONE)); GRPC_ERROR_UNREF(error); - } else { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - functor_callback, functor, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - error); + return; } + + // Schedule the shutdown callback on a closure if not internal or triggered + // from a background poller thread. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE( + functor_callback, functor, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), + error); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -1352,6 +1355,13 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); + if (grpc_iomgr_is_any_background_poller_thread()) { + grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); + return; + } + + // Schedule the shutdown callback on a closure if not internal or triggered + // from a background poller thread. GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( functor_callback, callback, From 7b0ee41fd5e48ba7d21d45511c0198bf520eda48 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 19 Jun 2019 10:28:35 -0700 Subject: [PATCH 385/676] Resolve comment --- include/grpcpp/impl/codegen/server_callback.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 6d83bc88e56..cd34ea3ff8c 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -348,7 +348,7 @@ class ServerBidiReactor : public internal::ServerReactor { private: friend class ServerCallbackReaderWriter; - // May be overridden by internal implementation details, this is not a public + // May be overridden by internal implementation details. This is not a public // customization point. virtual void InternalBindStream( ServerCallbackReaderWriter* stream) { @@ -385,7 +385,7 @@ class ServerReadReactor : public internal::ServerReactor { private: friend class ServerCallbackReader; - // May be overridden by internal implementation details, this is not a public + // May be overridden by internal implementation details. This is not a public // customization point. virtual void InternalBindReader(ServerCallbackReader* reader) { reader_ = reader; @@ -431,7 +431,7 @@ class ServerWriteReactor : public internal::ServerReactor { private: friend class ServerCallbackWriter; - // May be overridden by internal implementation details, this is not a public + // May be overridden by internal implementation details. This is not a public // customization point. virtual void InternalBindWriter(ServerCallbackWriter* writer) { writer_ = writer; From 6a7bbbc1bd4668d2001eed5c846e04f87bd353f8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 10:31:47 -0700 Subject: [PATCH 386/676] Fix objc tests pull request failures --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index b8f37560148..e2f52e73117 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -25,7 +25,7 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" + export RUN_TESTS_FLAGS="--filter_pr_tests --base_branch origin/$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH $RUN_TESTS_FLAGS" fi set +ex # rvm script is very verbose and exits with errorcode From ec8777c6aabcc912d3f5cc501e647ec72f90fa19 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Apr 2019 16:43:06 -0700 Subject: [PATCH 387/676] Add protobuf pod version sanitizer --- tools/distrib/check_protobuf_pod_version.sh | 46 +++++++++++++++++++++ tools/run_tests/sanity/sanity_tests.yaml | 1 + 2 files changed, 47 insertions(+) create mode 100755 tools/distrib/check_protobuf_pod_version.sh diff --git a/tools/distrib/check_protobuf_pod_version.sh b/tools/distrib/check_protobuf_pod_version.sh new file mode 100755 index 00000000000..174931a0d18 --- /dev/null +++ b/tools/distrib/check_protobuf_pod_version.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +cd `dirname $0`/../.. + +# get the version of protobuf in /third_party/protobuf +pushd third_party/protobuf + +version1=$(git describe --tags | cut -f 1 -d'-') +v1=${version1:1} + +popd + +# get the version of protobuf in /src/objective-c/!ProtoCompiler.podspec +v2=$(cat src/objective-c/\!ProtoCompiler.podspec | egrep "v = " | cut -f 2 -d"'") + +# get the version of protobuf in /src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +v3=$(cat src/objective-c/\!ProtoCompiler-gRPCPlugin.podspec | egrep 'dependency.*!ProtoCompiler' | cut -f 4 -d"'") + +# compare and emit error +ret=0 +if [ $v1 != $v2 ]; then + echo 'Protobuf version in src/objective-c/!ProtoCompiler.podspec does not match protobuf version in third_party/protobuf.' + ret=1 +fi + +if [ $v1 != $v3 ]; then + echo 'Protobuf version in src/objective-c/!ProtoCompiler-gRPCPlugin.podspec does not match protobuf version in third_party/protobuf.' + ret=1 +fi + +exit $ret diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index 1913edd4257..065be90108c 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -24,4 +24,5 @@ - script: tools/distrib/yapf_code.sh - script: tools/distrib/python/check_grpcio_tools.py - script: tools/distrib/check_shadow_boringssl_symbol_list.sh +- script: tools/distrib/check_protobuf_pod_version.sh cpu_cost: 1000 From 67e6b03e92626bc8c8f236b90bfa676ae7eadbc4 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 19 Jun 2019 11:34:01 -0700 Subject: [PATCH 388/676] Fix compression algorithm parsing --- .../message_compress_filter.cc | 254 ++++++++---------- src/core/lib/compression/compression.cc | 3 +- src/core/lib/compression/compression_args.cc | 19 +- src/core/lib/compression/compression_args.h | 5 +- .../lib/compression/compression_internal.cc | 2 +- src/core/lib/surface/call.cc | 11 +- test/core/compression/algorithm_test.cc | 15 +- test/core/compression/compression_test.cc | 4 +- test/core/end2end/fixtures/h2_compress.cc | 10 +- test/core/end2end/tests/compressed_payload.cc | 10 +- .../stream_compression_compressed_payload.cc | 12 +- .../tests/stream_compression_payload.cc | 10 +- .../stream_compression_ping_pong_streaming.cc | 10 +- .../tests/workaround_cronet_compression.cc | 4 +- 14 files changed, 178 insertions(+), 191 deletions(-) diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc index d2b1f6794cd..3ce79b305df 100644 --- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc +++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc @@ -45,18 +45,30 @@ static void send_message_on_complete(void* arg, grpc_error* error); static void on_send_message_next_done(void* arg, grpc_error* error); namespace { -enum initial_metadata_state { - // Initial metadata not yet seen. - INITIAL_METADATA_UNSEEN = 0, - // Initial metadata seen; compression algorithm set. - HAS_COMPRESSION_ALGORITHM, - // Initial metadata seen; no compression algorithm set. - NO_COMPRESSION_ALGORITHM, + +struct channel_data { + /** The default, channel-level, compression algorithm */ + grpc_compression_algorithm default_compression_algorithm; + /** Bitset of enabled compression algorithms */ + uint32_t enabled_compression_algorithms_bitset; + /** Bitset of enabled message compression algorithms */ + uint32_t enabled_message_compression_algorithms_bitset; + /** Bitset of enabled stream compression algorithms */ + uint32_t enabled_stream_compression_algorithms_bitset; }; struct call_data { call_data(grpc_call_element* elem, const grpc_call_element_args& args) : call_combiner(args.call_combiner) { + channel_data* channeld = static_cast(elem->channel_data); + // The call's message compression algorithm is set to channel's default + // setting. It can be overridden later by initial metadata. + if (GPR_LIKELY(GPR_BITGET(channeld->enabled_compression_algorithms_bitset, + channeld->default_compression_algorithm))) { + message_compression_algorithm = + grpc_compression_algorithm_to_message_compression_algorithm( + channeld->default_compression_algorithm); + } GRPC_CLOSURE_INIT(&start_send_message_batch_in_call_combiner, start_send_message_batch, elem, grpc_schedule_on_exec_ctx); @@ -73,15 +85,13 @@ struct call_data { } grpc_core::CallCombiner* call_combiner; - grpc_linked_mdelem compression_algorithm_storage; + grpc_linked_mdelem message_compression_algorithm_storage; grpc_linked_mdelem stream_compression_algorithm_storage; grpc_linked_mdelem accept_encoding_storage; grpc_linked_mdelem accept_stream_encoding_storage; - /** Compression algorithm we'll try to use. It may be given by incoming - * metadata, or by the channel's default compression settings. */ grpc_message_compression_algorithm message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE; - initial_metadata_state send_initial_metadata_state = INITIAL_METADATA_UNSEEN; + bool seen_initial_metadata = false; grpc_error* cancel_error = GRPC_ERROR_NONE; grpc_closure start_send_message_batch_in_call_combiner; grpc_transport_stream_op_batch* send_message_batch = nullptr; @@ -93,130 +103,104 @@ struct call_data { grpc_closure on_send_message_next_done; }; -struct channel_data { - /** The default, channel-level, compression algorithm */ - grpc_compression_algorithm default_compression_algorithm; - /** Bitset of enabled compression algorithms */ - uint32_t enabled_algorithms_bitset; - /** Supported compression algorithms */ - uint32_t supported_message_compression_algorithms; - /** Supported stream compression algorithms */ - uint32_t supported_stream_compression_algorithms; -}; } // namespace -static bool skip_compression(grpc_call_element* elem, uint32_t flags, - bool has_compression_algorithm) { +// Returns true if we should skip message compression for the current message. +static bool skip_message_compression(grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); - channel_data* channeld = static_cast(elem->channel_data); - + // If the flags of this message indicate that it shouldn't be compressed, we + // skip message compression. + uint32_t flags = + calld->send_message_batch->payload->send_message.send_message->flags(); if (flags & (GRPC_WRITE_NO_COMPRESS | GRPC_WRITE_INTERNAL_COMPRESS)) { return true; } - if (has_compression_algorithm) { - if (calld->message_compression_algorithm == GRPC_MESSAGE_COMPRESS_NONE) { - return true; - } - return false; /* we have an actual call-specific algorithm */ + // If this call doesn't have any message compression algorithm set, skip + // message compression. + return calld->message_compression_algorithm == GRPC_MESSAGE_COMPRESS_NONE; +} + +// Determines the compression algorithm from the initial metadata and the +// channel's default setting. +static grpc_compression_algorithm find_compression_algorithm( + grpc_metadata_batch* initial_metadata, channel_data* channeld) { + if (initial_metadata->idx.named.grpc_internal_encoding_request == nullptr) { + return channeld->default_compression_algorithm; } - /* no per-call compression override */ - return channeld->default_compression_algorithm == GRPC_COMPRESS_NONE; + grpc_compression_algorithm compression_algorithm; + // Parse the compression algorithm from the initial metadata. + grpc_mdelem md = + initial_metadata->idx.named.grpc_internal_encoding_request->md; + GPR_ASSERT(grpc_compression_algorithm_parse(GRPC_MDVALUE(md), + &compression_algorithm)); + // Remove this metadata since it's an internal one (i.e., it won't be + // transmitted out). + grpc_metadata_batch_remove( + initial_metadata, + initial_metadata->idx.named.grpc_internal_encoding_request); + // Check if that algorithm is enabled. Note that GRPC_COMPRESS_NONE is always + // enabled. + // TODO(juanlishen): Maybe use channel default or abort() if the algorithm + // from the initial metadata is disabled. + if (GPR_LIKELY(GPR_BITGET(channeld->enabled_compression_algorithms_bitset, + compression_algorithm))) { + return compression_algorithm; + } + const char* algorithm_name; + GPR_ASSERT( + grpc_compression_algorithm_name(compression_algorithm, &algorithm_name)); + gpr_log(GPR_ERROR, + "Invalid compression algorithm from initial metadata: '%s' " + "(previously disabled). " + "Will not compress.", + algorithm_name); + return GRPC_COMPRESS_NONE; } -/** Filter initial metadata */ static grpc_error* process_send_initial_metadata( - grpc_call_element* elem, grpc_metadata_batch* initial_metadata, - bool* has_compression_algorithm) GRPC_MUST_USE_RESULT; + grpc_call_element* elem, + grpc_metadata_batch* initial_metadata) GRPC_MUST_USE_RESULT; static grpc_error* process_send_initial_metadata( - grpc_call_element* elem, grpc_metadata_batch* initial_metadata, - bool* has_compression_algorithm) { + grpc_call_element* elem, grpc_metadata_batch* initial_metadata) { call_data* calld = static_cast(elem->call_data); channel_data* channeld = static_cast(elem->channel_data); - *has_compression_algorithm = false; - grpc_compression_algorithm compression_algorithm; + // Find the compression algorithm. + grpc_compression_algorithm compression_algorithm = + find_compression_algorithm(initial_metadata, channeld); + // Note that at most one of the following algorithms can be set. + calld->message_compression_algorithm = + grpc_compression_algorithm_to_message_compression_algorithm( + compression_algorithm); grpc_stream_compression_algorithm stream_compression_algorithm = - GRPC_STREAM_COMPRESS_NONE; - if (initial_metadata->idx.named.grpc_internal_encoding_request != nullptr) { - grpc_mdelem md = - initial_metadata->idx.named.grpc_internal_encoding_request->md; - if (GPR_UNLIKELY(!grpc_compression_algorithm_parse( - GRPC_MDVALUE(md), &compression_algorithm))) { - char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (unknown). Ignoring.", val); - gpr_free(val); - calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE; - stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE; - } - if (GPR_UNLIKELY(!GPR_BITGET(channeld->enabled_algorithms_bitset, - compression_algorithm))) { - char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, - "Invalid compression algorithm: '%s' (previously disabled). " - "Ignoring.", - val); - gpr_free(val); - calld->message_compression_algorithm = GRPC_MESSAGE_COMPRESS_NONE; - stream_compression_algorithm = GRPC_STREAM_COMPRESS_NONE; - } - *has_compression_algorithm = true; - grpc_metadata_batch_remove( - initial_metadata, - initial_metadata->idx.named.grpc_internal_encoding_request); - calld->message_compression_algorithm = - grpc_compression_algorithm_to_message_compression_algorithm( - compression_algorithm); - stream_compression_algorithm = - grpc_compression_algorithm_to_stream_compression_algorithm( - compression_algorithm); - } else { - /* If no algorithm was found in the metadata and we aren't - * exceptionally skipping compression, fall back to the channel - * default */ - if (channeld->default_compression_algorithm != GRPC_COMPRESS_NONE) { - calld->message_compression_algorithm = - grpc_compression_algorithm_to_message_compression_algorithm( - channeld->default_compression_algorithm); - stream_compression_algorithm = - grpc_compression_algorithm_to_stream_compression_algorithm( - channeld->default_compression_algorithm); - } - *has_compression_algorithm = true; - } - + grpc_compression_algorithm_to_stream_compression_algorithm( + compression_algorithm); + // Hint compression algorithm. grpc_error* error = GRPC_ERROR_NONE; - /* hint compression algorithm */ - if (stream_compression_algorithm != GRPC_STREAM_COMPRESS_NONE) { + if (calld->message_compression_algorithm != GRPC_MESSAGE_COMPRESS_NONE) { error = grpc_metadata_batch_add_tail( - initial_metadata, &calld->stream_compression_algorithm_storage, - grpc_stream_compression_encoding_mdelem(stream_compression_algorithm)); - } else if (calld->message_compression_algorithm != - GRPC_MESSAGE_COMPRESS_NONE) { - error = grpc_metadata_batch_add_tail( - initial_metadata, &calld->compression_algorithm_storage, + initial_metadata, &calld->message_compression_algorithm_storage, grpc_message_compression_encoding_mdelem( calld->message_compression_algorithm)); + } else if (stream_compression_algorithm != GRPC_STREAM_COMPRESS_NONE) { + error = grpc_metadata_batch_add_tail( + initial_metadata, &calld->stream_compression_algorithm_storage, + grpc_stream_compression_encoding_mdelem(stream_compression_algorithm)); } - if (error != GRPC_ERROR_NONE) return error; - - /* convey supported compression algorithms */ + // Convey supported compression algorithms. error = grpc_metadata_batch_add_tail( initial_metadata, &calld->accept_encoding_storage, GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS( - channeld->supported_message_compression_algorithms)); - + channeld->enabled_message_compression_algorithms_bitset)); if (error != GRPC_ERROR_NONE) return error; - - /* Do not overwrite accept-encoding header if it already presents (e.g. added - * by some proxy). */ + // Do not overwrite accept-encoding header if it already presents (e.g., added + // by some proxy). if (!initial_metadata->idx.named.accept_encoding) { error = grpc_metadata_batch_add_tail( initial_metadata, &calld->accept_stream_encoding_storage, GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS( - channeld->supported_stream_compression_algorithms)); + channeld->enabled_stream_compression_algorithms_bitset)); } - return error; } @@ -358,12 +342,7 @@ static void on_send_message_next_done(void* arg, grpc_error* error) { static void start_send_message_batch(void* arg, grpc_error* unused) { grpc_call_element* elem = static_cast(arg); - call_data* calld = static_cast(elem->call_data); - if (skip_compression( - elem, - calld->send_message_batch->payload->send_message.send_message - ->flags(), - calld->send_initial_metadata_state == HAS_COMPRESSION_ALGORITHM)) { + if (skip_message_compression(elem)) { send_message_batch_continue(elem); } else { continue_reading_send_message(elem); @@ -380,7 +359,7 @@ static void compress_start_transport_stream_op_batch( calld->cancel_error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); if (calld->send_message_batch != nullptr) { - if (calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN) { + if (!calld->seen_initial_metadata) { GRPC_CALL_COMBINER_START( calld->call_combiner, GRPC_CLOSURE_CREATE(fail_send_message_batch_in_call_combiner, calld, @@ -398,19 +377,15 @@ static void compress_start_transport_stream_op_batch( } // Handle send_initial_metadata. if (batch->send_initial_metadata) { - GPR_ASSERT(calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN); - bool has_compression_algorithm; + GPR_ASSERT(!calld->seen_initial_metadata); grpc_error* error = process_send_initial_metadata( - elem, batch->payload->send_initial_metadata.send_initial_metadata, - &has_compression_algorithm); + elem, batch->payload->send_initial_metadata.send_initial_metadata); if (error != GRPC_ERROR_NONE) { grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); return; } - calld->send_initial_metadata_state = has_compression_algorithm - ? HAS_COMPRESSION_ALGORITHM - : NO_COMPRESSION_ALGORITHM; + calld->seen_initial_metadata = true; // If we had previously received a batch containing a send_message op, // handle it now. Note that we need to re-enter the call combiner // for this, since we can't send two batches down while holding the @@ -431,7 +406,7 @@ static void compress_start_transport_stream_op_batch( // wait. We save the batch in calld and then drop the call // combiner, which we'll have to pick up again later when we get // send_initial_metadata. - if (calld->send_initial_metadata_state == INITIAL_METADATA_UNSEEN) { + if (!calld->seen_initial_metadata) { GRPC_CALL_COMBINER_STOP( calld->call_combiner, "send_message batch pending send_initial_metadata"); @@ -463,34 +438,29 @@ static void destroy_call_elem(grpc_call_element* elem, static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { channel_data* channeld = static_cast(elem->channel_data); - - channeld->enabled_algorithms_bitset = + // Get the enabled and the default algorithms from channel args. + channeld->enabled_compression_algorithms_bitset = grpc_channel_args_compression_algorithm_get_states(args->channel_args); channeld->default_compression_algorithm = - grpc_channel_args_get_compression_algorithm(args->channel_args); - - /* Make sure the default isn't disabled. */ - if (!GPR_BITGET(channeld->enabled_algorithms_bitset, + grpc_channel_args_get_channel_default_compression_algorithm( + args->channel_args); + // Make sure the default is enabled. + if (!GPR_BITGET(channeld->enabled_compression_algorithms_bitset, channeld->default_compression_algorithm)) { - gpr_log(GPR_DEBUG, - "compression algorithm %d not enabled: switching to none", - channeld->default_compression_algorithm); + const char* name; + GPR_ASSERT(grpc_compression_algorithm_name( + channeld->default_compression_algorithm, &name) == 1); + gpr_log(GPR_ERROR, + "default compression algorithm %s not enabled: switching to none", + name); channeld->default_compression_algorithm = GRPC_COMPRESS_NONE; } - - uint32_t supported_compression_algorithms = - (((1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1) & - channeld->enabled_algorithms_bitset) | - 1u; - - channeld->supported_message_compression_algorithms = + channeld->enabled_message_compression_algorithms_bitset = grpc_compression_bitset_to_message_bitset( - supported_compression_algorithms); - - channeld->supported_stream_compression_algorithms = + channeld->enabled_compression_algorithms_bitset); + channeld->enabled_stream_compression_algorithms_bitset = grpc_compression_bitset_to_stream_bitset( - supported_compression_algorithms); - + channeld->enabled_compression_algorithms_bitset); GPR_ASSERT(!args->is_last); return GRPC_ERROR_NONE; } diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc index a3a069d9266..2f35e5fa03f 100644 --- a/src/core/lib/compression/compression.cc +++ b/src/core/lib/compression/compression.cc @@ -59,12 +59,11 @@ int grpc_compression_algorithm_parse(grpc_slice name, } else { return 0; } - return 0; } int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm, const char** name) { - GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2, + GRPC_API_TRACE("grpc_compression_algorithm_name(algorithm=%d, name=%p)", 2, ((int)algorithm, name)); switch (algorithm) { case GRPC_COMPRESS_NONE: diff --git a/src/core/lib/compression/compression_args.cc b/src/core/lib/compression/compression_args.cc index 6a8232dc033..6bbda64e263 100644 --- a/src/core/lib/compression/compression_args.cc +++ b/src/core/lib/compression/compression_args.cc @@ -32,21 +32,25 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( +grpc_compression_algorithm +grpc_channel_args_get_channel_default_compression_algorithm( const grpc_channel_args* a) { size_t i; if (a == nullptr) return GRPC_COMPRESS_NONE; for (i = 0; i < a->num_args; ++i) { if (a->args[i].type == GRPC_ARG_INTEGER && !strcmp(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, a->args[i].key)) { - return static_cast(a->args[i].value.integer); - break; + grpc_compression_algorithm default_algorithm = + static_cast(a->args[i].value.integer); + return default_algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT + ? default_algorithm + : GRPC_COMPRESS_NONE; } } return GRPC_COMPRESS_NONE; } -grpc_channel_args* grpc_channel_args_set_compression_algorithm( +grpc_channel_args* grpc_channel_args_set_channel_default_compression_algorithm( grpc_channel_args* a, grpc_compression_algorithm algorithm) { GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT); grpc_arg tmp; @@ -68,7 +72,9 @@ static int find_compression_algorithm_states_bitset(const grpc_channel_args* a, !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, a->args[i].key)) { *states_arg = &a->args[i].value.integer; - **states_arg |= 0x1; /* forcefully enable support for no compression */ + **states_arg = + (**states_arg & ((1 << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1)) | + 0x1; /* forcefully enable support for no compression */ return 1; } } @@ -83,7 +89,8 @@ grpc_channel_args* grpc_channel_args_compression_algorithm_set_state( const int states_arg_found = find_compression_algorithm_states_bitset(*a, &states_arg); - if (grpc_channel_args_get_compression_algorithm(*a) == algorithm && + if (grpc_channel_args_get_channel_default_compression_algorithm(*a) == + algorithm && state == 0) { const char* algo_name = nullptr; GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0); diff --git a/src/core/lib/compression/compression_args.h b/src/core/lib/compression/compression_args.h index 407d6e2b8ca..f1abc122cea 100644 --- a/src/core/lib/compression/compression_args.h +++ b/src/core/lib/compression/compression_args.h @@ -25,13 +25,14 @@ #include /** Returns the compression algorithm set in \a a. */ -grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( +grpc_compression_algorithm +grpc_channel_args_get_channel_default_compression_algorithm( const grpc_channel_args* a); /** Returns a channel arg instance with compression enabled. If \a a is * non-NULL, its args are copied. N.B. GRPC_COMPRESS_NONE disables compression * for the channel. */ -grpc_channel_args* grpc_channel_args_set_compression_algorithm( +grpc_channel_args* grpc_channel_args_set_channel_default_compression_algorithm( grpc_channel_args* a, grpc_compression_algorithm algorithm); /** Sets the support for the given compression algorithm. By default, all diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc index e0d73ef6d83..e0cf6d45194 100644 --- a/src/core/lib/compression/compression_internal.cc +++ b/src/core/lib/compression/compression_internal.cc @@ -171,7 +171,7 @@ int grpc_compression_algorithm_from_message_stream_compression_algorithm( int grpc_message_compression_algorithm_name( grpc_message_compression_algorithm algorithm, const char** name) { GRPC_API_TRACE( - "grpc_message_compression_algorithm_parse(algorithm=%d, name=%p)", 2, + "grpc_message_compression_algorithm_name(algorithm=%d, name=%p)", 2, ((int)algorithm, name)); switch (algorithm) { case GRPC_MESSAGE_COMPRESS_NONE: diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 2ccd3355594..13b1d126393 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1568,6 +1568,10 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS; goto done_with_error; } + // TODO(juanlishen): If the user has already specified a compression + // algorithm by setting the initial metadata with key of + // GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, we shouldn't override that + // with the compression algorithm mapped from compression level. /* process compression level */ grpc_metadata& compression_md = call->compression_md; compression_md.key = grpc_empty_slice(); @@ -1589,17 +1593,18 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, effective_compression_level = copts.default_level.level; } } + // Currently, only server side supports compression level setting. if (level_set && !call->is_client) { const grpc_compression_algorithm calgo = compression_algorithm_for_level_locked( call, effective_compression_level); - /* the following will be picked up by the compress filter and used - * as the call's compression algorithm. */ + // The following metadata will be checked and removed by the message + // compression filter. It will be used as the call's compression + // algorithm. compression_md.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST; compression_md.value = grpc_compression_algorithm_slice(calgo); additional_metadata_count++; } - if (op->data.send_initial_metadata.count + additional_metadata_count > INT_MAX) { error = GRPC_CALL_ERROR_INVALID_METADATA; diff --git a/test/core/compression/algorithm_test.cc b/test/core/compression/algorithm_test.cc index 24fe83774b8..c32820f08f4 100644 --- a/test/core/compression/algorithm_test.cc +++ b/test/core/compression/algorithm_test.cc @@ -80,20 +80,20 @@ static void test_algorithm_mesh(void) { } static void test_algorithm_failure(void) { - grpc_core::ExecCtx exec_ctx; - grpc_slice mdstr; - gpr_log(GPR_DEBUG, "test_algorithm_failure"); - + // Test invalid algorithm name + grpc_slice mdstr = + grpc_slice_from_static_string("this-is-an-invalid-algorithm"); + GPR_ASSERT(grpc_compression_algorithm_from_slice(mdstr) == + GRPC_COMPRESS_ALGORITHMS_COUNT); + grpc_slice_unref_internal(mdstr); + // Test invalid algorithm enum entry. GPR_ASSERT(grpc_compression_algorithm_name(GRPC_COMPRESS_ALGORITHMS_COUNT, nullptr) == 0); GPR_ASSERT( grpc_compression_algorithm_name(static_cast( GRPC_COMPRESS_ALGORITHMS_COUNT + 1), nullptr) == 0); - mdstr = grpc_slice_from_static_string("this-is-an-invalid-algorithm"); - GPR_ASSERT(grpc_compression_algorithm_from_slice(mdstr) == - GRPC_COMPRESS_ALGORITHMS_COUNT); GPR_ASSERT(grpc_slice_eq( grpc_compression_algorithm_slice(GRPC_COMPRESS_ALGORITHMS_COUNT), grpc_empty_slice())); @@ -101,7 +101,6 @@ static void test_algorithm_failure(void) { grpc_compression_algorithm_slice(static_cast( static_cast(GRPC_COMPRESS_ALGORITHMS_COUNT) + 1)), grpc_empty_slice())); - grpc_slice_unref_internal(mdstr); } int main(int argc, char** argv) { diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index cf6d18847e6..aa54241135c 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -265,8 +265,8 @@ static void test_channel_args_set_compression_algorithm(void) { grpc_core::ExecCtx exec_ctx; grpc_channel_args* ch_args; - ch_args = - grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP); + ch_args = grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_GZIP); GPR_ASSERT(ch_args->num_args == 1); GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0); diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index f97192fecaa..01e5ae1b7b5 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -69,8 +69,9 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f, grpc_core::ExecCtx exec_ctx; grpc_channel_args_destroy(ffd->client_args_compression); } - ffd->client_args_compression = grpc_channel_args_set_compression_algorithm( - client_args, GRPC_COMPRESS_GZIP); + ffd->client_args_compression = + grpc_channel_args_set_channel_default_compression_algorithm( + client_args, GRPC_COMPRESS_GZIP); f->client = grpc_insecure_channel_create( ffd->localaddr, ffd->client_args_compression, nullptr); } @@ -83,8 +84,9 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, grpc_core::ExecCtx exec_ctx; grpc_channel_args_destroy(ffd->server_args_compression); } - ffd->server_args_compression = grpc_channel_args_set_compression_algorithm( - server_args, GRPC_COMPRESS_GZIP); + ffd->server_args_compression = + grpc_channel_args_set_channel_default_compression_algorithm( + server_args, GRPC_COMPRESS_GZIP); if (f->server) { grpc_server_destroy(f->server); } diff --git a/test/core/end2end/tests/compressed_payload.cc b/test/core/end2end/tests/compressed_payload.cc index 2b9ab5d642a..81e6bfccd10 100644 --- a/test/core/end2end/tests/compressed_payload.cc +++ b/test/core/end2end/tests/compressed_payload.cc @@ -124,10 +124,10 @@ static void request_for_disabled_algorithm( request_payload_slice = grpc_slice_from_copied_string(str); request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - client_args = grpc_channel_args_set_compression_algorithm( + client_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, requested_client_compression_algorithm); - server_args = - grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_NONE); + server_args = grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_NONE); { grpc_core::ExecCtx exec_ctx; server_args = grpc_channel_args_compression_algorithm_set_state( @@ -308,9 +308,9 @@ static void request_with_payload_template( grpc_slice response_payload_slice = grpc_slice_from_copied_string(response_str); - client_args = grpc_channel_args_set_compression_algorithm( + client_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_client_channel_compression_algorithm); - server_args = grpc_channel_args_set_compression_algorithm( + server_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_server_channel_compression_algorithm); f = begin_test(config, test_name, client_args, server_args); diff --git a/test/core/end2end/tests/stream_compression_compressed_payload.cc b/test/core/end2end/tests/stream_compression_compressed_payload.cc index 39f95b85baa..9f40da100b4 100644 --- a/test/core/end2end/tests/stream_compression_compressed_payload.cc +++ b/test/core/end2end/tests/stream_compression_compressed_payload.cc @@ -124,10 +124,10 @@ static void request_for_disabled_algorithm( request_payload_slice = grpc_slice_from_copied_string(str); request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - client_args = grpc_channel_args_set_compression_algorithm( + client_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, requested_client_compression_algorithm); - server_args = - grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_NONE); + server_args = grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_NONE); { grpc_core::ExecCtx exec_ctx; server_args = grpc_channel_args_compression_algorithm_set_state( @@ -310,13 +310,13 @@ static void request_with_payload_template( grpc_slice response_payload_slice = grpc_slice_from_copied_string(response_str); - client_args = grpc_channel_args_set_compression_algorithm( + client_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_client_channel_compression_algorithm); if (set_default_server_message_compression_algorithm) { - server_args = grpc_channel_args_set_compression_algorithm( + server_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_server_message_compression_algorithm); } else { - server_args = grpc_channel_args_set_compression_algorithm( + server_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_server_channel_compression_algorithm); } diff --git a/test/core/end2end/tests/stream_compression_payload.cc b/test/core/end2end/tests/stream_compression_payload.cc index 5f6b9a7f199..ba0557facac 100644 --- a/test/core/end2end/tests/stream_compression_payload.cc +++ b/test/core/end2end/tests/stream_compression_payload.cc @@ -263,10 +263,12 @@ static void request_response_with_payload(grpc_end2end_test_config config, payload and status. */ static void test_invoke_request_response_with_payload( grpc_end2end_test_config config) { - grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm( - nullptr, GRPC_COMPRESS_STREAM_GZIP); - grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm( - nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* client_args = + grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* server_args = + grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); grpc_end2end_test_fixture f = begin_test(config, "test_invoke_request_response_with_payload", client_args, server_args); diff --git a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc index 6e96f7d2938..39698bde442 100644 --- a/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc +++ b/test/core/end2end/tests/stream_compression_ping_pong_streaming.cc @@ -91,10 +91,12 @@ static void end_test(grpc_end2end_test_fixture* f) { /* Client pings and server pongs. Repeat messages rounds before finishing. */ static void test_pingpong_streaming(grpc_end2end_test_config config, int messages) { - grpc_channel_args* client_args = grpc_channel_args_set_compression_algorithm( - nullptr, GRPC_COMPRESS_STREAM_GZIP); - grpc_channel_args* server_args = grpc_channel_args_set_compression_algorithm( - nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* client_args = + grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); + grpc_channel_args* server_args = + grpc_channel_args_set_channel_default_compression_algorithm( + nullptr, GRPC_COMPRESS_STREAM_GZIP); grpc_end2end_test_fixture f = begin_test(config, "test_pingpong_streaming", client_args, server_args); grpc_call* c; diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index d79b2a9be3b..1a47244b68d 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -136,9 +136,9 @@ static void request_with_payload_template( grpc_slice response_payload_slice = grpc_slice_from_copied_string(response_str); - client_args = grpc_channel_args_set_compression_algorithm( + client_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_client_channel_compression_algorithm); - server_args = grpc_channel_args_set_compression_algorithm( + server_args = grpc_channel_args_set_channel_default_compression_algorithm( nullptr, default_server_channel_compression_algorithm); if (user_agent_override) { From 8cc345777659c8dec31f42be448fd0a97b96ad44 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 13:48:37 -0700 Subject: [PATCH 389/676] fix tests so that they run --- tools/run_tests/run_tests.py | 145 +++++++++++++++++------------------ 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index e5506063091..f251c06d371 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1058,79 +1058,78 @@ class ObjCLanguage(object): def test_specs(self): out = [] - if self.config == 'dbg': - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' - }) - out += job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample-frameworks', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', - 'FRAMEWORKS': 'YES' - }) - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-switftsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'SwiftSample', - 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_plugin_tests.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-plugintest', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=20 * 60, - shortname='ios-test-cfstream-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-unittests', - cpu_cost=1e6, - environ={ - SCHEME: 'UnitTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-interoptests', - cpu_cost=1e6, - environ={ - SCHEME: 'InteropTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-cronettests', - cpu_cost=1e6, - environ={ - SCHEME: 'CronetTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='mac-test-basictests', - cpu_cost=1e6, - environ={ - SCHEME: 'MacTests' - }) + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' + }) + out += job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample-frameworks', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', + 'FRAMEWORKS': 'YES' + }) + out += self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-switftsample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'SwiftSample', + 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_plugin_tests.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-plugintest', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], + timeout_seconds=20 * 60, + shortname='ios-test-cfstream-tests', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-unittests', + cpu_cost=1e6, + environ={ + SCHEME: 'UnitTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-interoptests', + cpu_cost=1e6, + environ={ + SCHEME: 'InteropTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-cronettests', + cpu_cost=1e6, + environ={ + SCHEME: 'CronetTests' + }) + out += self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='mac-test-basictests', + cpu_cost=1e6, + environ={ + SCHEME: 'MacTests' + }) return sorted(out) From 03797e0ec36e76f08ecb51c74ebec0531d24fac4 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Mon, 17 Jun 2019 04:41:46 +0000 Subject: [PATCH 390/676] Simplify and fix the c-ares TCP path on Windows --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 480 +++++++++++++++--- 1 file changed, 401 insertions(+), 79 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 7d5215938e3..df40ba1c4bd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -31,6 +31,9 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iocp_windows.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" #include "src/core/lib/iomgr/tcp_windows.h" #include "src/core/lib/slice/slice_internal.h" @@ -50,6 +53,32 @@ struct iovec { namespace grpc_core { +/* c-ares reads and takes action on the error codes of the + * "virtual socket operations" in this file, via the WSAGetLastError + * APIs. If code in this file wants to set a specific WSA error that + * c-ares should read, it must do so by calling SetWSAError() on the + * WSAErrorContext instance passed to it. A WSAErrorContext must only be + * instantiated at the top of the virtual socket function callstack. */ +class WSAErrorContext { + public: + explicit WSAErrorContext(){}; + + ~WSAErrorContext() { + if (error_ != 0) { + WSASetLastError(error_); + } + } + + /* Disallow copy and assignment operators */ + WSAErrorContext(const WSAErrorContext&) = delete; + WSAErrorContext& operator=(const WSAErrorContext&) = delete; + + void SetWSAError(int error) { error_ = error; } + + private: + int error_ = 0; +}; + /* c-ares creates its own sockets and is meant to read them when readable and * write them when writeable. To fit this socket usage model into the grpc * windows poller (which gives notifications when attempted reads and writes are @@ -68,11 +97,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd { WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY, }; - GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner) + GrpcPolledFdWindows(ares_socket_t as, grpc_combiner* combiner, + int address_family, int socket_type) : read_buf_(grpc_empty_slice()), write_buf_(grpc_empty_slice()), - write_state_(WRITE_IDLE), - gotten_into_driver_list_(false) { + tcp_write_state_(WRITE_IDLE), + gotten_into_driver_list_(false), + address_family_(address_family), + socket_type_(socket_type) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, as); winsocket_ = grpc_winsocket_create(as, name_); combiner_ = GRPC_COMBINER_REF(combiner, name_); @@ -82,6 +114,16 @@ class GrpcPolledFdWindows : public GrpcPolledFd { GRPC_CLOSURE_INIT(&outer_write_closure_, &GrpcPolledFdWindows::OnIocpWriteable, this, grpc_combiner_scheduler(combiner_)); + GRPC_CLOSURE_INIT(&on_tcp_connect_locked_, + &GrpcPolledFdWindows::OnTcpConnectLocked, this, + grpc_combiner_scheduler(combiner_)); + GRPC_CLOSURE_INIT(&continue_register_for_on_readable_locked_, + &GrpcPolledFdWindows::ContinueRegisterForOnReadableLocked, + this, grpc_combiner_scheduler(combiner_)); + GRPC_CLOSURE_INIT( + &continue_register_for_on_writeable_locked_, + &GrpcPolledFdWindows::ContinueRegisterForOnWriteableLocked, this, + grpc_combiner_scheduler(combiner_)); } ~GrpcPolledFdWindows() { @@ -111,6 +153,33 @@ class GrpcPolledFdWindows : public GrpcPolledFd { grpc_slice_unref_internal(read_buf_); GPR_ASSERT(!read_buf_has_data_); read_buf_ = GRPC_SLICE_MALLOC(4192); + if (connect_done_) { + GRPC_CLOSURE_SCHED(&continue_register_for_on_readable_locked_, + GRPC_ERROR_NONE); + } else { + GPR_ASSERT(pending_continue_register_for_on_readable_locked_ == nullptr); + pending_continue_register_for_on_readable_locked_ = + &continue_register_for_on_readable_locked_; + } + } + + static void ContinueRegisterForOnReadableLocked(void* arg, + grpc_error* unused_error) { + GrpcPolledFdWindows* grpc_polled_fd = + static_cast(arg); + grpc_polled_fd->InnerContinueRegisterForOnReadableLocked(GRPC_ERROR_NONE); + } + + void InnerContinueRegisterForOnReadableLocked(grpc_error* unused_error) { + GRPC_CARES_TRACE_LOG( + "fd:|%s| InnerContinueRegisterForOnReadableLocked " + "wsa_connect_error_:%d", + GetName(), wsa_connect_error_); + GPR_ASSERT(connect_done_); + if (wsa_connect_error_ != 0) { + ScheduleAndNullReadClosure(GRPC_WSA_ERROR(wsa_connect_error_, "connect")); + return; + } WSABUF buffer; buffer.buf = (char*)GRPC_SLICE_START_PTR(read_buf_); buffer.len = GRPC_SLICE_LENGTH(read_buf_); @@ -123,13 +192,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd { &winsocket_->read_info.overlapped, nullptr)) { int wsa_last_error = WSAGetLastError(); char* msg = gpr_format_message(wsa_last_error); - grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); GRPC_CARES_TRACE_LOG( - "RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg, - GetName()); + "fd:|%s| RegisterForOnReadableLocked WSARecvFrom error code:|%d| " + "msg:|%s|", + GetName(), wsa_last_error, msg); gpr_free(msg); if (wsa_last_error != WSA_IO_PENDING) { - ScheduleAndNullReadClosure(error); + ScheduleAndNullReadClosure( + GRPC_WSA_ERROR(wsa_last_error, "WSARecvFrom")); return; } } @@ -137,23 +207,68 @@ class GrpcPolledFdWindows : public GrpcPolledFd { } void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { - GRPC_CARES_TRACE_LOG( - "RegisterForOnWriteableLocked. fd:|%s|. Current write state: %d", - GetName(), write_state_); + if (socket_type_ == SOCK_DGRAM) { + GRPC_CARES_TRACE_LOG("fd:|%s| RegisterForOnWriteableLocked called", + GetName()); + } else { + GPR_ASSERT(socket_type_ == SOCK_STREAM); + GRPC_CARES_TRACE_LOG( + "fd:|%s| RegisterForOnWriteableLocked called tcp_write_state_: %d", + GetName(), tcp_write_state_); + } GPR_ASSERT(write_closure_ == nullptr); write_closure_ = write_closure; - switch (write_state_) { - case WRITE_IDLE: - ScheduleAndNullWriteClosure(GRPC_ERROR_NONE); - break; - case WRITE_REQUESTED: - write_state_ = WRITE_PENDING; - SendWriteBuf(nullptr, &winsocket_->write_info.overlapped); - grpc_socket_notify_on_write(winsocket_, &outer_write_closure_); - break; - case WRITE_PENDING: - case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY: - abort(); + if (connect_done_) { + GRPC_CLOSURE_SCHED(&continue_register_for_on_writeable_locked_, + GRPC_ERROR_NONE); + } else { + GPR_ASSERT(pending_continue_register_for_on_writeable_locked_ == nullptr); + pending_continue_register_for_on_writeable_locked_ = + &continue_register_for_on_writeable_locked_; + } + } + + static void ContinueRegisterForOnWriteableLocked(void* arg, + grpc_error* unused_error) { + GrpcPolledFdWindows* grpc_polled_fd = + static_cast(arg); + grpc_polled_fd->InnerContinueRegisterForOnWriteableLocked(GRPC_ERROR_NONE); + } + + void InnerContinueRegisterForOnWriteableLocked(grpc_error* unused_error) { + GRPC_CARES_TRACE_LOG( + "fd:|%s| InnerContinueRegisterForOnWriteableLocked " + "wsa_connect_error_:%d", + GetName(), wsa_connect_error_); + GPR_ASSERT(connect_done_); + if (wsa_connect_error_ != 0) { + ScheduleAndNullWriteClosure( + GRPC_WSA_ERROR(wsa_connect_error_, "connect")); + return; + } + if (socket_type_ == SOCK_DGRAM) { + ScheduleAndNullWriteClosure(GRPC_ERROR_NONE); + } else { + GPR_ASSERT(socket_type_ == SOCK_STREAM); + int wsa_error_code = 0; + switch (tcp_write_state_) { + case WRITE_IDLE: + ScheduleAndNullWriteClosure(GRPC_ERROR_NONE); + break; + case WRITE_REQUESTED: + tcp_write_state_ = WRITE_PENDING; + if (SendWriteBuf(nullptr, &winsocket_->write_info.overlapped, + &wsa_error_code) != 0) { + ScheduleAndNullWriteClosure( + GRPC_WSA_ERROR(wsa_error_code, "WSASend (overlapped)")); + } else { + grpc_socket_notify_on_write(winsocket_, &outer_write_closure_); + } + break; + case WRITE_PENDING: + case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY: + abort(); + } } } @@ -171,13 +286,15 @@ class GrpcPolledFdWindows : public GrpcPolledFd { const char* GetName() override { return name_; } - ares_ssize_t RecvFrom(void* data, ares_socket_t data_len, int flags, + ares_ssize_t RecvFrom(WSAErrorContext* wsa_error_ctx, void* data, + ares_socket_t data_len, int flags, struct sockaddr* from, ares_socklen_t* from_len) { GRPC_CARES_TRACE_LOG( - "RecvFrom called on fd:|%s|. Current read buf length:|%d|", GetName(), - GRPC_SLICE_LENGTH(read_buf_)); + "fd:|%s| RecvFrom called read_buf_has_data:%d Current read buf " + "length:|%d|", + GetName(), read_buf_has_data_, GRPC_SLICE_LENGTH(read_buf_)); if (!read_buf_has_data_) { - WSASetLastError(WSAEWOULDBLOCK); + wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); return -1; } ares_ssize_t bytes_read = 0; @@ -215,54 +332,99 @@ class GrpcPolledFdWindows : public GrpcPolledFd { return out; } - int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped) { + int SendWriteBuf(LPDWORD bytes_sent_ptr, LPWSAOVERLAPPED overlapped, + int* wsa_error_code) { WSABUF buf; buf.len = GRPC_SLICE_LENGTH(write_buf_); buf.buf = (char*)GRPC_SLICE_START_PTR(write_buf_); DWORD flags = 0; int out = WSASend(grpc_winsocket_wrapped_socket(winsocket_), &buf, 1, bytes_sent_ptr, flags, overlapped, nullptr); + *wsa_error_code = WSAGetLastError(); GRPC_CARES_TRACE_LOG( - "WSASend: name:%s. buf len:%d. bytes sent: %d. overlapped %p. return " - "val: %d", - GetName(), buf.len, *bytes_sent_ptr, overlapped, out); + "fd:|%s| SendWriteBuf WSASend buf.len:%d *bytes_sent_ptr:%d " + "overlapped:%p " + "return:%d *wsa_error_code:%d", + GetName(), buf.len, bytes_sent_ptr != nullptr ? *bytes_sent_ptr : 0, + overlapped, out, *wsa_error_code); return out; } - ares_ssize_t TrySendWriteBufSyncNonBlocking() { - GPR_ASSERT(write_state_ == WRITE_IDLE); + ares_ssize_t SendV(WSAErrorContext* wsa_error_ctx, const struct iovec* iov, + int iov_count) { + GRPC_CARES_TRACE_LOG( + "fd:|%s| SendV called connect_done_:%d was_connect_error_:%d", + GetName(), connect_done_, wsa_connect_error_); + if (!connect_done_) { + wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); + return -1; + } + if (wsa_connect_error_ != 0) { + wsa_error_ctx->SetWSAError(wsa_connect_error_); + return -1; + } + switch (socket_type_) { + case SOCK_DGRAM: + return SendVUDP(wsa_error_ctx, iov, iov_count); + case SOCK_STREAM: + return SendVTCP(wsa_error_ctx, iov, iov_count); + default: + abort(); + } + } + + ares_ssize_t SendVUDP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov, + int iov_count) { + // c-ares doesn't handle retryable errors on writes of UDP sockets. + // Therefore, the sendv handler for UDP sockets must only attempt + // to write everything inline. + GRPC_CARES_TRACE_LOG("fd:|%s| SendVUDP called", GetName()); + GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0); + grpc_slice_unref_internal(write_buf_); + write_buf_ = FlattenIovec(iov, iov_count); DWORD bytes_sent = 0; - if (SendWriteBuf(&bytes_sent, nullptr) != 0) { - int wsa_last_error = WSAGetLastError(); - char* msg = gpr_format_message(wsa_last_error); + int wsa_error_code = 0; + if (SendWriteBuf(&bytes_sent, nullptr, &wsa_error_code) != 0) { + wsa_error_ctx->SetWSAError(wsa_error_code); + char* msg = gpr_format_message(wsa_error_code); GRPC_CARES_TRACE_LOG( - "TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|", - msg, GetName()); + "fd:|%s| SendVUDP SendWriteBuf error code:%d msg:|%s|", GetName(), + wsa_error_code, msg); gpr_free(msg); - if (wsa_last_error == WSA_IO_PENDING) { - WSASetLastError(WSAEWOULDBLOCK); - write_state_ = WRITE_REQUESTED; - } + return -1; } write_buf_ = grpc_slice_sub_no_ref(write_buf_, bytes_sent, GRPC_SLICE_LENGTH(write_buf_)); return bytes_sent; } - ares_ssize_t SendV(const struct iovec* iov, int iov_count) { - GRPC_CARES_TRACE_LOG("SendV called on fd:|%s|. Current write state: %d", - GetName(), write_state_); - switch (write_state_) { + ares_ssize_t SendVTCP(WSAErrorContext* wsa_error_ctx, const struct iovec* iov, + int iov_count) { + // The "sendv" handler on TCP sockets buffers up write + // requests and returns an artifical WSAEWOULDBLOCK. Writing that buffer out + // in the background, and making further send progress in general, will + // happen as long as c-ares continues to show interest in writeability on + // this fd. + GRPC_CARES_TRACE_LOG("fd:|%s| SendVTCP called tcp_write_state_:%d", + GetName(), tcp_write_state_); + switch (tcp_write_state_) { case WRITE_IDLE: + tcp_write_state_ = WRITE_REQUESTED; GPR_ASSERT(GRPC_SLICE_LENGTH(write_buf_) == 0); grpc_slice_unref_internal(write_buf_); write_buf_ = FlattenIovec(iov, iov_count); - return TrySendWriteBufSyncNonBlocking(); + wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); + return -1; case WRITE_REQUESTED: case WRITE_PENDING: - WSASetLastError(WSAEWOULDBLOCK); + wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); return -1; case WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY: + // c-ares is retrying a send on data that we previously returned + // WSAEWOULDBLOCK for, but then subsequently wrote out in the + // background. Right now, we assume that c-ares is retrying the same + // send again. If c-ares still needs to send even more data, we'll get + // to it eventually. grpc_slice currently_attempted = FlattenIovec(iov, iov_count); GPR_ASSERT(GRPC_SLICE_LENGTH(currently_attempted) >= GRPC_SLICE_LENGTH(write_buf_)); @@ -272,31 +434,159 @@ class GrpcPolledFdWindows : public GrpcPolledFd { GRPC_SLICE_START_PTR(write_buf_)[i]); total_sent++; } - grpc_slice_unref_internal(write_buf_); - write_buf_ = - grpc_slice_sub_no_ref(currently_attempted, total_sent, - GRPC_SLICE_LENGTH(currently_attempted)); - write_state_ = WRITE_IDLE; - total_sent += TrySendWriteBufSyncNonBlocking(); + grpc_slice_unref_internal(currently_attempted); + tcp_write_state_ = WRITE_IDLE; return total_sent; } abort(); } - int Connect(const struct sockaddr* target, ares_socklen_t target_len) { + static void OnTcpConnectLocked(void* arg, grpc_error* error) { + GrpcPolledFdWindows* grpc_polled_fd = + static_cast(arg); + grpc_polled_fd->InnerOnTcpConnectLocked(error); + } + + void InnerOnTcpConnectLocked(grpc_error* error) { + GRPC_CARES_TRACE_LOG( + "fd:%s InnerOnTcpConnectLocked error:|%s| " + "pending_register_for_readable:%" PRIdPTR + " pending_register_for_writeable:%" PRIdPTR, + GetName(), grpc_error_string(error), + pending_continue_register_for_on_readable_locked_, + pending_continue_register_for_on_writeable_locked_); + GPR_ASSERT(!connect_done_); + connect_done_ = true; + GPR_ASSERT(wsa_connect_error_ == 0); + if (error == GRPC_ERROR_NONE) { + DWORD transfered_bytes = 0; + DWORD flags; + BOOL wsa_success = WSAGetOverlappedResult( + grpc_winsocket_wrapped_socket(winsocket_), + &winsocket_->write_info.overlapped, &transfered_bytes, FALSE, &flags); + GPR_ASSERT(transfered_bytes == 0); + if (!wsa_success) { + wsa_connect_error_ = WSAGetLastError(); + char* msg = gpr_format_message(wsa_connect_error_); + GRPC_CARES_TRACE_LOG( + "fd:%s InnerOnTcpConnectLocked WSA overlapped result code:%d " + "msg:|%s|", + GetName(), wsa_connect_error_, msg); + gpr_free(msg); + } + } else { + // Spoof up an error code that will cause any future c-ares operations on + // this fd to abort. + wsa_connect_error_ = WSA_OPERATION_ABORTED; + } + if (pending_continue_register_for_on_readable_locked_ != nullptr) { + GRPC_CLOSURE_SCHED(pending_continue_register_for_on_readable_locked_, + GRPC_ERROR_NONE); + } + if (pending_continue_register_for_on_writeable_locked_ != nullptr) { + GRPC_CLOSURE_SCHED(pending_continue_register_for_on_writeable_locked_, + GRPC_ERROR_NONE); + } + } + + int Connect(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target, + ares_socklen_t target_len) { + switch (socket_type_) { + case SOCK_DGRAM: + return ConnectUDP(wsa_error_ctx, target, target_len); + case SOCK_STREAM: + return ConnectTCP(wsa_error_ctx, target, target_len); + default: + abort(); + } + } + + int ConnectUDP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target, + ares_socklen_t target_len) { + GRPC_CARES_TRACE_LOG("fd:%s ConnectUDP", GetName()); + GPR_ASSERT(!connect_done_); + GPR_ASSERT(wsa_connect_error_ == 0); SOCKET s = grpc_winsocket_wrapped_socket(winsocket_); - GRPC_CARES_TRACE_LOG("Connect: fd:|%s|", GetName()); int out = WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr); - if (out != 0) { + wsa_connect_error_ = WSAGetLastError(); + wsa_error_ctx->SetWSAError(wsa_connect_error_); + connect_done_ = true; + char* msg = gpr_format_message(wsa_connect_error_); + GRPC_CARES_TRACE_LOG("fd:%s WSAConnect error code:|%d| msg:|%s|", GetName(), + wsa_connect_error_, msg); + gpr_free(msg); + // c-ares expects a posix-style connect API + return out == 0 ? 0 : -1; + } + + int ConnectTCP(WSAErrorContext* wsa_error_ctx, const struct sockaddr* target, + ares_socklen_t target_len) { + GRPC_CARES_TRACE_LOG("fd:%s ConnectTCP", GetName()); + LPFN_CONNECTEX ConnectEx; + GUID guid = WSAID_CONNECTEX; + DWORD ioctl_num_bytes; + SOCKET s = grpc_winsocket_wrapped_socket(winsocket_); + if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), + &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, nullptr, + nullptr) != 0) { + int wsa_last_error = WSAGetLastError(); + wsa_error_ctx->SetWSAError(wsa_last_error); + char* msg = gpr_format_message(wsa_last_error); + GRPC_CARES_TRACE_LOG( + "fd:%s WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER) error code:%d " + "msg:|%s|", + GetName(), wsa_last_error, msg); + gpr_free(msg); + connect_done_ = true; + wsa_connect_error_ = wsa_last_error; + return -1; + } + grpc_resolved_address wildcard4_addr; + grpc_resolved_address wildcard6_addr; + grpc_sockaddr_make_wildcards(0, &wildcard4_addr, &wildcard6_addr); + grpc_resolved_address* local_address = nullptr; + if (address_family_ == AF_INET) { + local_address = &wildcard4_addr; + } else { + local_address = &wildcard6_addr; + } + if (bind(s, (struct sockaddr*)local_address->addr, + (int)local_address->len) != 0) { int wsa_last_error = WSAGetLastError(); + wsa_error_ctx->SetWSAError(wsa_last_error); char* msg = gpr_format_message(wsa_last_error); - GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|", - wsa_last_error, msg, GetName()); + GRPC_CARES_TRACE_LOG("fd:%s bind error code:%d msg:|%s|", GetName(), + wsa_last_error, msg); gpr_free(msg); - // c-ares expects a posix-style connect API + connect_done_ = true; + wsa_connect_error_ = wsa_last_error; + return -1; + } + int out = 0; + if (ConnectEx(s, target, target_len, nullptr, 0, nullptr, + &winsocket_->write_info.overlapped) == 0) { out = -1; + int wsa_last_error = WSAGetLastError(); + wsa_error_ctx->SetWSAError(wsa_last_error); + char* msg = gpr_format_message(wsa_last_error); + GRPC_CARES_TRACE_LOG("fd:%s ConnectEx error code:%d msg:|%s|", GetName(), + wsa_last_error, msg); + gpr_free(msg); + if (wsa_last_error == WSA_IO_PENDING) { + // c-ares only understands WSAEINPROGRESS and EWOULDBLOCK error codes on + // connect, but an async connect on IOCP socket will give + // WSA_IO_PENDING, so we need to convert. + wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); + } else { + // By returning a non-retryable error to c-ares at this point, + // we're aborting the possibility of any future operations on this fd. + connect_done_ = true; + wsa_connect_error_ = wsa_last_error; + return -1; + } } + grpc_socket_notify_on_write(winsocket_, &on_tcp_connect_locked_); return out; } @@ -319,12 +609,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd { * in subsequent c-ares reads. */ if (winsocket_->read_info.wsa_error != WSAEMSGSIZE) { GRPC_ERROR_UNREF(error); - char* msg = gpr_format_message(winsocket_->read_info.wsa_error); + error = GRPC_WSA_ERROR(winsocket_->read_info.wsa_error, + "OnIocpReadableInner"); GRPC_CARES_TRACE_LOG( - "OnIocpReadableInner. winsocket error:|%s|. fd:|%s|", msg, - GetName()); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + "fd:|%s| OnIocpReadableInner winsocket_->read_info.wsa_error " + "code:|%d| msg:|%s|", + GetName(), winsocket_->read_info.wsa_error, + grpc_error_string(error)); } } } @@ -337,8 +628,8 @@ class GrpcPolledFdWindows : public GrpcPolledFd { read_buf_ = grpc_empty_slice(); } GRPC_CARES_TRACE_LOG( - "OnIocpReadable finishing. read buf length now:|%d|. :fd:|%s|", - GRPC_SLICE_LENGTH(read_buf_), GetName()); + "fd:|%s| OnIocpReadable finishing. read buf length now:|%d|", GetName(), + GRPC_SLICE_LENGTH(read_buf_)); ScheduleAndNullReadClosure(error); } @@ -349,22 +640,26 @@ class GrpcPolledFdWindows : public GrpcPolledFd { void OnIocpWriteableInner(grpc_error* error) { GRPC_CARES_TRACE_LOG("OnIocpWriteableInner. fd:|%s|", GetName()); + GPR_ASSERT(socket_type_ == SOCK_STREAM); if (error == GRPC_ERROR_NONE) { if (winsocket_->write_info.wsa_error != 0) { - char* msg = gpr_format_message(winsocket_->write_info.wsa_error); - GRPC_CARES_TRACE_LOG( - "OnIocpWriteableInner. winsocket error:|%s|. fd:|%s|", msg, - GetName()); GRPC_ERROR_UNREF(error); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + error = GRPC_WSA_ERROR(winsocket_->write_info.wsa_error, + "OnIocpWriteableInner"); + GRPC_CARES_TRACE_LOG( + "fd:|%s| OnIocpWriteableInner. winsocket_->write_info.wsa_error " + "code:|%d| msg:|%s|", + GetName(), winsocket_->write_info.wsa_error, + grpc_error_string(error)); } } - GPR_ASSERT(write_state_ == WRITE_PENDING); + GPR_ASSERT(tcp_write_state_ == WRITE_PENDING); if (error == GRPC_ERROR_NONE) { - write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY; + tcp_write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY; write_buf_ = grpc_slice_sub_no_ref( write_buf_, 0, winsocket_->write_info.bytes_transfered); + GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d", + GetName(), winsocket_->write_info.bytes_transfered); } else { grpc_slice_unref_internal(write_buf_); write_buf_ = grpc_empty_slice(); @@ -386,9 +681,22 @@ class GrpcPolledFdWindows : public GrpcPolledFd { grpc_closure outer_read_closure_; grpc_closure outer_write_closure_; grpc_winsocket* winsocket_; - WriteState write_state_; + // tcp_write_state_ is only used on TCP GrpcPolledFds + WriteState tcp_write_state_; char* name_ = nullptr; bool gotten_into_driver_list_; + int address_family_; + int socket_type_; + grpc_closure on_tcp_connect_locked_; + bool connect_done_ = false; + int wsa_connect_error_ = 0; + // We don't run register_for_{readable,writeable} logic until + // a socket is connected. In the interim, we queue readable/writeable + // registrations with the following state. + grpc_closure continue_register_for_on_readable_locked_; + grpc_closure continue_register_for_on_writeable_locked_; + grpc_closure* pending_continue_register_for_on_readable_locked_ = nullptr; + grpc_closure* pending_continue_register_for_on_writeable_locked_ = nullptr; }; struct SockToPolledFdEntry { @@ -454,39 +762,53 @@ class SockToPolledFdMap { * objects. */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { + if (type != SOCK_DGRAM && type != SOCK_STREAM) { + GRPC_CARES_TRACE_LOG("Socket called with invalid socket type:%d", type); + return INVALID_SOCKET; + } SockToPolledFdMap* map = static_cast(user_data); SOCKET s = WSASocket(af, type, protocol, nullptr, 0, grpc_get_default_wsa_socket_flags()); if (s == INVALID_SOCKET) { + GRPC_CARES_TRACE_LOG( + "WSASocket failed with params af:%d type:%d protocol:%d", af, type, + protocol); return s; } grpc_tcp_set_non_block(s); GrpcPolledFdWindows* polled_fd = - New(s, map->combiner_); + New(s, map->combiner_, af, type); + GRPC_CARES_TRACE_LOG( + "fd:|%s| created with params af:%d type:%d protocol:%d", + polled_fd->GetName(), af, type, protocol); map->AddNewSocket(s, polled_fd); return s; } static int Connect(ares_socket_t as, const struct sockaddr* target, ares_socklen_t target_len, void* user_data) { + WSAErrorContext wsa_error_ctx; SockToPolledFdMap* map = static_cast(user_data); GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as); - return polled_fd->Connect(target, target_len); + return polled_fd->Connect(&wsa_error_ctx, target, target_len); } static ares_ssize_t SendV(ares_socket_t as, const struct iovec* iov, int iovec_count, void* user_data) { + WSAErrorContext wsa_error_ctx; SockToPolledFdMap* map = static_cast(user_data); GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as); - return polled_fd->SendV(iov, iovec_count); + return polled_fd->SendV(&wsa_error_ctx, iov, iovec_count); } static ares_ssize_t RecvFrom(ares_socket_t as, void* data, size_t data_len, int flags, struct sockaddr* from, ares_socklen_t* from_len, void* user_data) { + WSAErrorContext wsa_error_ctx; SockToPolledFdMap* map = static_cast(user_data); GrpcPolledFdWindows* polled_fd = map->LookupPolledFd(as); - return polled_fd->RecvFrom(data, data_len, flags, from, from_len); + return polled_fd->RecvFrom(&wsa_error_ctx, data, data_len, flags, from, + from_len); } static int CloseSocket(SOCKET s, void* user_data) { From 8a11a8120ac4f7a97a3b58676580f805c7430129 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 14:48:50 -0700 Subject: [PATCH 391/676] More run_tests.py script fix --- src/objective-c/tests/run_one_test.sh | 0 tools/run_tests/run_tests.py | 153 ++++++++++++++------------ 2 files changed, 81 insertions(+), 72 deletions(-) mode change 100644 => 100755 src/objective-c/tests/run_one_test.sh diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh old mode 100644 new mode 100755 diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index f251c06d371..0addc093d73 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1058,78 +1058,87 @@ class ObjCLanguage(object): def test_specs(self): out = [] - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' - }) - out += job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-sample-frameworks', - cpu_cost=1e6, - environ={ - 'SCHEME': 'Sample', - 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', - 'FRAMEWORKS': 'YES' - }) - out += self.config.job_spec( - ['src/objective-c/tests/build_one_example.sh'], - timeout_seconds=10 * 60, - shortname='ios-buildtest-example-switftsample', - cpu_cost=1e6, - environ={ - 'SCHEME': 'SwiftSample', - 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_plugin_tests.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-plugintest', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=20 * 60, - shortname='ios-test-cfstream-tests', - cpu_cost=1e6, - environ=_FORCE_ENVIRON_FOR_WRAPPERS) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-unittests', - cpu_cost=1e6, - environ={ - SCHEME: 'UnitTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-interoptests', - cpu_cost=1e6, - environ={ - SCHEME: 'InteropTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='ios-test-cronettests', - cpu_cost=1e6, - environ={ - SCHEME: 'CronetTests' - }) - out += self.config.job_spec( - ['src/objective-c/tests/run_one_test.sh'], - timeout_seconds=60 * 60, - shortname='mac-test-basictests', - cpu_cost=1e6, - environ={ - SCHEME: 'MacTests' - }) + out.append( + self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-sample-frameworks', + cpu_cost=1e6, + environ={ + 'SCHEME': 'Sample', + 'EXAMPLE_PATH': 'src/objective-c/examples/Sample', + 'FRAMEWORKS': 'YES' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/build_one_example.sh'], + timeout_seconds=10 * 60, + shortname='ios-buildtest-example-switftsample', + cpu_cost=1e6, + environ={ + 'SCHEME': 'SwiftSample', + 'EXAMPLE_PATH': 'src/objective-c/examples/SwiftSample' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/run_plugin_tests.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-plugintest', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS)) + out.append( + self.config.job_spec( + ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], + timeout_seconds=20 * 60, + shortname='ios-test-cfstream-tests', + cpu_cost=1e6, + environ=_FORCE_ENVIRON_FOR_WRAPPERS)) + out.append( + self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-unittests', + cpu_cost=1e6, + environ={ + 'SCHEME': 'UnitTests' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-interoptests', + cpu_cost=1e6, + environ={ + 'SCHEME': 'InteropTests' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='ios-test-cronettests', + cpu_cost=1e6, + environ={ + 'SCHEME': 'CronetTests' + })) + out.append( + self.config.job_spec( + ['src/objective-c/tests/run_one_test.sh'], + timeout_seconds=60 * 60, + shortname='mac-test-basictests', + cpu_cost=1e6, + environ={ + 'SCHEME': 'MacTests' + })) return sorted(out) From 3e843d68d09ac49600b2bcbd4bf42941119cbb10 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 19 Jun 2019 14:59:26 -0700 Subject: [PATCH 392/676] Skip all ruby distrib tests that use ruby 2.2 --- tools/run_tests/artifacts/distribtest_targets.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index fd68a4dc747..1e861029faa 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -336,17 +336,18 @@ def targets(): PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True), PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True), RubyDistribTest('linux', 'x64', 'wheezy'), - RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_2'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_3'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), - RubyDistribTest('linux', 'x64', 'centos6'), - RubyDistribTest('linux', 'x64', 'centos7'), - RubyDistribTest('linux', 'x64', 'fedora20'), - RubyDistribTest('linux', 'x64', 'fedora21'), - RubyDistribTest('linux', 'x64', 'fedora22'), - RubyDistribTest('linux', 'x64', 'fedora23'), + # TODO(apolcyn): unskip these after upgrading the ruby versions + # of these dockerfiles to >= 2.3. + # RubyDistribTest('linux', 'x64', 'centos6'), + # RubyDistribTest('linux', 'x64', 'centos7'), + # RubyDistribTest('linux', 'x64', 'fedora20'), + # RubyDistribTest('linux', 'x64', 'fedora21'), + # RubyDistribTest('linux', 'x64', 'fedora22'), + # RubyDistribTest('linux', 'x64', 'fedora23'), RubyDistribTest('linux', 'x64', 'opensuse'), RubyDistribTest('linux', 'x64', 'ubuntu1204'), RubyDistribTest('linux', 'x64', 'ubuntu1404'), From 621707370aa5d546e1325a61de7eab8e1db36b18 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 19 Jun 2019 14:59:26 -0700 Subject: [PATCH 393/676] Skip all ruby distrib tests that use ruby 2.2 --- tools/run_tests/artifacts/distribtest_targets.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index fd68a4dc747..1e861029faa 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -336,17 +336,18 @@ def targets(): PythonDistribTest('linux', 'x64', 'ubuntu1404', source=True), PythonDistribTest('linux', 'x64', 'ubuntu1604', source=True), RubyDistribTest('linux', 'x64', 'wheezy'), - RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_2'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_3'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), - RubyDistribTest('linux', 'x64', 'centos6'), - RubyDistribTest('linux', 'x64', 'centos7'), - RubyDistribTest('linux', 'x64', 'fedora20'), - RubyDistribTest('linux', 'x64', 'fedora21'), - RubyDistribTest('linux', 'x64', 'fedora22'), - RubyDistribTest('linux', 'x64', 'fedora23'), + # TODO(apolcyn): unskip these after upgrading the ruby versions + # of these dockerfiles to >= 2.3. + # RubyDistribTest('linux', 'x64', 'centos6'), + # RubyDistribTest('linux', 'x64', 'centos7'), + # RubyDistribTest('linux', 'x64', 'fedora20'), + # RubyDistribTest('linux', 'x64', 'fedora21'), + # RubyDistribTest('linux', 'x64', 'fedora22'), + # RubyDistribTest('linux', 'x64', 'fedora23'), RubyDistribTest('linux', 'x64', 'opensuse'), RubyDistribTest('linux', 'x64', 'ubuntu1204'), RubyDistribTest('linux', 'x64', 'ubuntu1404'), From 5255b49fbc3b810bd56df31a2f9ea98cf5ff9c8c Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 15:40:22 -0700 Subject: [PATCH 394/676] fix run_one_test --- src/objective-c/tests/run_one_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh index 04cba0e321a..342d5a5b38d 100755 --- a/src/objective-c/tests/run_one_test.sh +++ b/src/objective-c/tests/run_one_test.sh @@ -47,7 +47,7 @@ XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ xcodebuild \ -workspace Tests.xcworkspace \ - -scheme SCHEME \ + -scheme $SCHEME \ -destination name="iPhone 8" \ HOST_PORT_LOCALSSL=localhost:$TLS_PORT \ HOST_PORT_LOCAL=localhost:$PLAIN_PORT \ From ad22f9d7bffc00aed71ef00d97b4639bb3795e60 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 16:24:59 -0700 Subject: [PATCH 395/676] Add delete operator overload --- BUILD | 4 ++-- BUILD.gn | 6 +++--- CMakeLists.txt | 12 ++++++------ Makefile | 12 ++++++------ build.yaml | 4 ++-- config.m4 | 4 ++-- config.w32 | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 6 +++--- grpc.gemspec | 4 ++-- grpc.gyp | 8 ++++---- package.xml | 4 ++-- .../iomgr/{threadpool => executor}/mpmcqueue.cc | 2 +- .../iomgr/{threadpool => executor}/mpmcqueue.h | 17 +++++++++++++---- src/python/grpcio/grpc_core_dependencies.py | 2 +- test/core/iomgr/mpmcqueue_test.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core.internal | 4 ++-- .../generated/sources_and_headers.json | 6 +++--- 19 files changed, 58 insertions(+), 49 deletions(-) rename src/core/lib/iomgr/{threadpool => executor}/mpmcqueue.cc (98%) rename src/core/lib/iomgr/{threadpool => executor}/mpmcqueue.h (92%) diff --git a/BUILD b/BUILD index 9abcf7ece9a..a3d1ab01ae2 100644 --- a/BUILD +++ b/BUILD @@ -837,7 +837,7 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server_windows.cc", "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", - "src/core/lib/iomgr/threadpool/mpmcqueue.cc", + "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/timer.cc", "src/core/lib/iomgr/timer_custom.cc", @@ -983,7 +983,7 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/threadpool/mpmcqueue.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/BUILD.gn b/BUILD.gn index 2ec4609c06d..dfb6e781fec 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -524,6 +524,8 @@ config("grpc_config") { "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.cc", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname.h", @@ -622,8 +624,6 @@ config("grpc_config") { "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/threadpool/mpmcqueue.cc", - "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.cc", @@ -1228,6 +1228,7 @@ config("grpc_config") { "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -1269,7 +1270,6 @@ config("grpc_config") { "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 7438eaf37cc..625513dce77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1027,6 +1027,7 @@ add_library(grpc src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1084,7 +1085,6 @@ add_library(grpc src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -1463,6 +1463,7 @@ add_library(grpc_cronet src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1520,7 +1521,6 @@ add_library(grpc_cronet src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -1881,6 +1881,7 @@ add_library(grpc_test_util src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1938,7 +1939,6 @@ add_library(grpc_test_util src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -2212,6 +2212,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2269,7 +2270,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -2519,6 +2519,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2576,7 +2577,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc @@ -3546,6 +3546,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/ev_windows.cc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/executor/mpmcqueue.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -3603,7 +3604,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/tcp_server_windows.cc src/core/lib/iomgr/tcp_uv.cc src/core/lib/iomgr/tcp_windows.cc - src/core/lib/iomgr/threadpool/mpmcqueue.cc src/core/lib/iomgr/time_averaged_stats.cc src/core/lib/iomgr/timer.cc src/core/lib/iomgr/timer_custom.cc diff --git a/Makefile b/Makefile index 717402673b4..3668555e49f 100644 --- a/Makefile +++ b/Makefile @@ -3520,6 +3520,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -3577,7 +3578,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -3950,6 +3950,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4007,7 +4008,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4361,6 +4361,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4418,7 +4419,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4679,6 +4679,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4736,7 +4737,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -4960,6 +4960,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -5017,7 +5018,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -5960,6 +5960,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -6017,7 +6018,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ diff --git a/build.yaml b/build.yaml index a02d7f01fcb..876e3a54440 100644 --- a/build.yaml +++ b/build.yaml @@ -280,6 +280,7 @@ filegroups: - src/core/lib/iomgr/ev_windows.cc - src/core/lib/iomgr/exec_ctx.cc - src/core/lib/iomgr/executor.cc + - src/core/lib/iomgr/executor/mpmcqueue.cc - src/core/lib/iomgr/fork_posix.cc - src/core/lib/iomgr/fork_windows.cc - src/core/lib/iomgr/gethostname_fallback.cc @@ -337,7 +338,6 @@ filegroups: - src/core/lib/iomgr/tcp_server_windows.cc - src/core/lib/iomgr/tcp_uv.cc - src/core/lib/iomgr/tcp_windows.cc - - src/core/lib/iomgr/threadpool/mpmcqueue.cc - src/core/lib/iomgr/time_averaged_stats.cc - src/core/lib/iomgr/timer.cc - src/core/lib/iomgr/timer_custom.cc @@ -467,6 +467,7 @@ filegroups: - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h + - src/core/lib/iomgr/executor/mpmcqueue.h - src/core/lib/iomgr/gethostname.h - src/core/lib/iomgr/grpc_if_nametoindex.h - src/core/lib/iomgr/internal_errqueue.h @@ -508,7 +509,6 @@ filegroups: - src/core/lib/iomgr/tcp_server.h - src/core/lib/iomgr/tcp_server_utils_posix.h - src/core/lib/iomgr/tcp_windows.h - - src/core/lib/iomgr/threadpool/mpmcqueue.h - src/core/lib/iomgr/time_averaged_stats.h - src/core/lib/iomgr/timer.h - src/core/lib/iomgr/timer_custom.h diff --git a/config.m4 b/config.m4 index 6782f94a2b2..da088819b86 100644 --- a/config.m4 +++ b/config.m4 @@ -127,6 +127,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/ev_windows.cc \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ + src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -184,7 +185,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ - src/core/lib/iomgr/threadpool/mpmcqueue.cc \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/timer.cc \ src/core/lib/iomgr/timer_custom.cc \ @@ -727,7 +727,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gprpp) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr) - PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr/threadpool) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr/executor) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context) diff --git a/config.w32 b/config.w32 index 8bff737f51f..fe62ac3f75b 100644 --- a/config.w32 +++ b/config.w32 @@ -102,6 +102,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\ev_windows.cc " + "src\\core\\lib\\iomgr\\exec_ctx.cc " + "src\\core\\lib\\iomgr\\executor.cc " + + "src\\core\\lib\\iomgr\\executor\\mpmcqueue.cc " + "src\\core\\lib\\iomgr\\fork_posix.cc " + "src\\core\\lib\\iomgr\\fork_windows.cc " + "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + @@ -159,7 +160,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\tcp_server_windows.cc " + "src\\core\\lib\\iomgr\\tcp_uv.cc " + "src\\core\\lib\\iomgr\\tcp_windows.cc " + - "src\\core\\lib\\iomgr\\threadpool\\mpmcqueue.cc " + "src\\core\\lib\\iomgr\\time_averaged_stats.cc " + "src\\core\\lib\\iomgr\\timer.cc " + "src\\core\\lib\\iomgr\\timer_custom.cc " + @@ -740,7 +740,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gprpp"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr"); - FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr\\threadpool"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr\\executor"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 55e7e9340a1..2c2bed861c4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -466,6 +466,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -507,7 +508,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', - 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', @@ -671,6 +671,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -712,7 +713,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', - 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 56b3d5b0955..ba96b5e86f2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -436,6 +436,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -477,7 +478,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', - 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', @@ -590,6 +590,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -647,7 +648,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -1091,6 +1091,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', + 'src/core/lib/iomgr/executor/mpmcqueue.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -1132,7 +1133,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/tcp_server.h', 'src/core/lib/iomgr/tcp_server_utils_posix.h', 'src/core/lib/iomgr/tcp_windows.h', - 'src/core/lib/iomgr/threadpool/mpmcqueue.h', 'src/core/lib/iomgr/time_averaged_stats.h', 'src/core/lib/iomgr/timer.h', 'src/core/lib/iomgr/timer_custom.h', diff --git a/grpc.gemspec b/grpc.gemspec index 3703533b6d7..65cc9a54f2c 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -370,6 +370,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) + s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) @@ -411,7 +412,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/tcp_server.h ) s.files += %w( src/core/lib/iomgr/tcp_server_utils_posix.h ) s.files += %w( src/core/lib/iomgr/tcp_windows.h ) - s.files += %w( src/core/lib/iomgr/threadpool/mpmcqueue.h ) s.files += %w( src/core/lib/iomgr/time_averaged_stats.h ) s.files += %w( src/core/lib/iomgr/timer.h ) s.files += %w( src/core/lib/iomgr/timer_custom.h ) @@ -524,6 +524,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/ev_windows.cc ) s.files += %w( src/core/lib/iomgr/exec_ctx.cc ) s.files += %w( src/core/lib/iomgr/executor.cc ) + s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.cc ) s.files += %w( src/core/lib/iomgr/fork_posix.cc ) s.files += %w( src/core/lib/iomgr/fork_windows.cc ) s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) @@ -581,7 +582,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/tcp_server_windows.cc ) s.files += %w( src/core/lib/iomgr/tcp_uv.cc ) s.files += %w( src/core/lib/iomgr/tcp_windows.cc ) - s.files += %w( src/core/lib/iomgr/threadpool/mpmcqueue.cc ) s.files += %w( src/core/lib/iomgr/time_averaged_stats.cc ) s.files += %w( src/core/lib/iomgr/timer.cc ) s.files += %w( src/core/lib/iomgr/timer_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index f64c80c2008..92d34f1557a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -309,6 +309,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -366,7 +367,6 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -686,6 +686,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -743,7 +744,6 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -937,6 +937,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -994,7 +995,6 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', @@ -1164,6 +1164,7 @@ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -1221,7 +1222,6 @@ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', diff --git a/package.xml b/package.xml index 77162f3d366..5c982926a8c 100644 --- a/package.xml +++ b/package.xml @@ -375,6 +375,7 @@ + @@ -416,7 +417,6 @@ - @@ -529,6 +529,7 @@ + @@ -586,7 +587,6 @@ - diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc similarity index 98% rename from src/core/lib/iomgr/threadpool/mpmcqueue.cc rename to src/core/lib/iomgr/executor/mpmcqueue.cc index f39abe572c0..ea29fe9e7e6 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -18,7 +18,7 @@ #include -#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" +#include "src/core/lib/iomgr/executor/mpmcqueue.h" #include #include diff --git a/src/core/lib/iomgr/threadpool/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h similarity index 92% rename from src/core/lib/iomgr/threadpool/mpmcqueue.h rename to src/core/lib/iomgr/executor/mpmcqueue.h index 2d77a281c5b..33240eaf6f6 100644 --- a/src/core/lib/iomgr/threadpool/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H -#define GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H +#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H #include @@ -53,7 +53,7 @@ class MPMCQueue : public MPMCQueueInterface { public: // Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created // will have infinite length. - explicit MPMCQueue(); + MPMCQueue(); // Release all resources hold by the queue. The queue must be empty, and no // one waiting on conditional variables. @@ -72,6 +72,15 @@ class MPMCQueue : public MPMCQueueInterface { // quickly. int count() const { return count_.Load(MemoryOrder::RELAXED); } + void* operator new(size_t n) { + void* p = gpr_malloc(n); + return p; + } + + void operator delete(void* p) { + gpr_free(p); + } + private: void* PopFront(); @@ -122,4 +131,4 @@ class MPMCQueue : public MPMCQueueInterface { } // namespace grpc_core -#endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_MPMCQUEUE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index fc9979f418e..5e04cc564fb 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -101,6 +101,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/ev_windows.cc', 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', + 'src/core/lib/iomgr/executor/mpmcqueue.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -158,7 +159,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/tcp_server_windows.cc', 'src/core/lib/iomgr/tcp_uv.cc', 'src/core/lib/iomgr/tcp_windows.cc', - 'src/core/lib/iomgr/threadpool/mpmcqueue.cc', 'src/core/lib/iomgr/time_averaged_stats.cc', 'src/core/lib/iomgr/timer.cc', 'src/core/lib/iomgr/timer_custom.cc', diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index e40a350c18c..9fa09153708 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -16,7 +16,7 @@ * */ -#include "src/core/lib/iomgr/threadpool/mpmcqueue.h" +#include "src/core/lib/iomgr/executor/mpmcqueue.h" #include #include diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e5e78ffbb4b..68db69546b8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1131,6 +1131,7 @@ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ +src/core/lib/iomgr/executor/mpmcqueue.h \ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/grpc_if_nametoindex.h \ src/core/lib/iomgr/internal_errqueue.h \ @@ -1172,7 +1173,6 @@ src/core/lib/iomgr/tcp_posix.h \ src/core/lib/iomgr/tcp_server.h \ src/core/lib/iomgr/tcp_server_utils_posix.h \ src/core/lib/iomgr/tcp_windows.h \ -src/core/lib/iomgr/threadpool/mpmcqueue.h \ src/core/lib/iomgr/time_averaged_stats.h \ src/core/lib/iomgr/timer.h \ src/core/lib/iomgr/timer_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 83a9315d5af..a79b213d49f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1233,6 +1233,8 @@ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor.h \ +src/core/lib/iomgr/executor/mpmcqueue.cc \ +src/core/lib/iomgr/executor/mpmcqueue.h \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname.h \ @@ -1331,8 +1333,6 @@ src/core/lib/iomgr/tcp_server_windows.cc \ src/core/lib/iomgr/tcp_uv.cc \ src/core/lib/iomgr/tcp_windows.cc \ src/core/lib/iomgr/tcp_windows.h \ -src/core/lib/iomgr/threadpool/mpmcqueue.cc \ -src/core/lib/iomgr/threadpool/mpmcqueue.h \ src/core/lib/iomgr/time_averaged_stats.cc \ src/core/lib/iomgr/time_averaged_stats.h \ src/core/lib/iomgr/timer.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3fad15ca046..6a420677811 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8442,6 +8442,7 @@ "src/core/lib/iomgr/ev_windows.cc", "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -8499,7 +8500,6 @@ "src/core/lib/iomgr/tcp_server_windows.cc", "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", - "src/core/lib/iomgr/threadpool/mpmcqueue.cc", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/timer.cc", "src/core/lib/iomgr/timer_custom.cc", @@ -8630,6 +8630,7 @@ "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -8671,7 +8672,6 @@ "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", @@ -8788,6 +8788,7 @@ "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -8829,7 +8830,6 @@ "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/threadpool/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", From 01ffaf8bac76359058c0f040a2c68efd0b0ee59c Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 16:34:40 -0700 Subject: [PATCH 396/676] Add GRPC Abstract Macro --- src/core/lib/iomgr/executor/mpmcqueue.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 33240eaf6f6..c710600fddf 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -24,8 +24,9 @@ #include #include -#include "src/core/lib/debug/stats.h" +#include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/sync.h" namespace grpc_core { @@ -39,14 +40,14 @@ class MPMCQueueInterface { // Put elem into queue immediately at the end of queue. // This might cause to block on full queue depending on implementation. - virtual void Put(void* elem) = 0; + virtual void Put(void* elem) GRPC_ABSTRACT; // Remove the oldest element from the queue and return it. // This might cause to block on empty queue depending on implementation. - virtual void* Get() = 0; + virtual void* Get() GRPC_ABSTRACT; // Return number of elements in the queue currently - virtual int count() const = 0; + virtual int count() const GRPC_ABSTRACT; }; class MPMCQueue : public MPMCQueueInterface { @@ -72,14 +73,7 @@ class MPMCQueue : public MPMCQueueInterface { // quickly. int count() const { return count_.Load(MemoryOrder::RELAXED); } - void* operator new(size_t n) { - void* p = gpr_malloc(n); - return p; - } - - void operator delete(void* p) { - gpr_free(p); - } + GRPC_ABSTRACT_BASE_CLASS private: void* PopFront(); From 1c6e8a07258102affe790deb9e1d9a737eaac69a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 16:41:41 -0700 Subject: [PATCH 397/676] Change getpagesize for portability --- src/core/lib/gprpp/thd_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 965a3ba229a..e26ee507a3d 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -50,7 +50,7 @@ struct thd_arg { }; size_t RoundUpToPageSize(size_t size) { - size_t page_size = static_cast(getpagesize()); + size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); return (size + page_size - 1) & ~(page_size - 1); } From 58e36f10344051ba98fa07b069df96742f8a97d7 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 16:55:06 -0700 Subject: [PATCH 398/676] Add base class abstract macro to all classes --- src/core/lib/iomgr/executor/mpmcqueue.h | 2 ++ test/core/iomgr/mpmcqueue_test.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index c710600fddf..0fdd1d2d5a0 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -48,6 +48,8 @@ class MPMCQueueInterface { // Return number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS }; class MPMCQueue : public MPMCQueueInterface { diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 9fa09153708..10a934ed149 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -141,6 +141,8 @@ class WorkThread { void Start() { thd_.Start(); } void Join() { thd_.Join(); } + GRPC_ABSTRACT_BASE_CLASS + private: void Run() { items_ = new WorkItem*[num_items_]; From 54c05c48956b6282c58b21b97d57fcfa89e04b28 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 16:59:39 -0700 Subject: [PATCH 399/676] Remove extra status print --- src/core/lib/iomgr/executor/mpmcqueue.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index ea29fe9e7e6..286267fce43 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -81,9 +81,6 @@ MPMCQueue::~MPMCQueue() { GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); MutexLock l(&mu_); GPR_ASSERT(num_waiters_ == 0); - if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { - PrintStats(); - } } void MPMCQueue::Put(void* elem) { From 2fbd77aee45c60cfda583f5373e33c3cc86ef506 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 17:16:23 -0700 Subject: [PATCH 400/676] Fix Node compile error on operator overload --- src/core/lib/iomgr/executor/mpmcqueue.h | 1 + test/core/iomgr/mpmcqueue_test.cc | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 0fdd1d2d5a0..e19b66241fb 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -92,6 +92,7 @@ class MPMCQueue : public MPMCQueueInterface { next = nullptr; insert_time = gpr_now(GPR_CLOCK_PRECISE); } + GRPC_ABSTRACT_BASE_CLASS }; struct Stats { // Stats of queue diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 10a934ed149..9fa09153708 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -141,8 +141,6 @@ class WorkThread { void Start() { thd_.Start(); } void Join() { thd_.Join(); } - GRPC_ABSTRACT_BASE_CLASS - private: void Run() { items_ = new WorkItem*[num_items_]; From a3a5685d298c7f57f6ba61b03848c8a88a8e52aa Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 17:40:56 -0700 Subject: [PATCH 401/676] Modify Node allocate/deallocate --- src/core/lib/iomgr/executor/mpmcqueue.cc | 7 +++++-- src/core/lib/iomgr/executor/mpmcqueue.h | 5 +---- test/core/iomgr/mpmcqueue_test.cc | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 286267fce43..d7266b433a3 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -45,7 +45,7 @@ inline void* MPMCQueue::PopFront() { gpr_timespec wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); - delete head_to_remove; + gpr_free(head_to_remove); // Update Stats info stats_.num_completed++; @@ -86,7 +86,10 @@ MPMCQueue::~MPMCQueue() { void MPMCQueue::Put(void* elem) { MutexLock l(&mu_); - Node* new_node = static_cast(new Node(elem)); + Node* new_node = static_cast(gpr_malloc(sizeof(Node))); + new_node->next = nullptr; + new_node->content = elem; + new_node->insert_time = gpr_now(GPR_CLOCK_PRECISE); if (count_.Load(MemoryOrder::RELAXED) == 0) { busy_time = gpr_now(GPR_CLOCK_PRECISE); queue_head_ = queue_tail_ = new_node; diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index e19b66241fb..2f27ab3b9c9 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -47,9 +47,7 @@ class MPMCQueueInterface { virtual void* Get() GRPC_ABSTRACT; // Return number of elements in the queue currently - virtual int count() const GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS + virtual int count() const GRPC_ABSTRACT; }; class MPMCQueue : public MPMCQueueInterface { @@ -92,7 +90,6 @@ class MPMCQueue : public MPMCQueueInterface { next = nullptr; insert_time = gpr_now(GPR_CLOCK_PRECISE); } - GRPC_ABSTRACT_BASE_CLASS }; struct Stats { // Stats of queue diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 9fa09153708..12799d7895e 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -58,6 +58,7 @@ static void test_small_queue(void) { GPR_ASSERT(i == item->index); delete item; } + gpr_log(GPR_DEBUG, "Done."); } static void test_get_thd(void* args) { From 53eef664d3d8b2245ea98d6299127348919c20e5 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 19 Jun 2019 18:00:49 -0700 Subject: [PATCH 402/676] clang-format --- src/core/lib/iomgr/executor/mpmcqueue.cc | 5 ++--- src/core/lib/iomgr/executor/mpmcqueue.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index d7266b433a3..7dc7be87e79 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -20,14 +20,13 @@ #include "src/core/lib/iomgr/executor/mpmcqueue.h" -#include -#include - #include #include #include #include #include +#include +#include #include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/sync.h" diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 2f27ab3b9c9..39396eeaad0 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -24,9 +24,9 @@ #include #include +#include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/atomic.h" -#include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/sync.h" namespace grpc_core { From a75acbb6ae31cf242b0a080791fead613ac2d470 Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Wed, 19 Jun 2019 19:25:44 -0700 Subject: [PATCH 403/676] Unref unselected subchannels in Pick First. --- .../lb_policy/pick_first/pick_first.cc | 117 +++++++++--------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 00036d8be64..e0deed27442 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -128,6 +128,10 @@ class PickFirst : public LoadBalancingPolicy { void ShutdownLocked() override; + void AttemptToConnectUsingLatestUpdateArgsLocked(); + + // Lateset update args. + UpdateArgs latest_update_args_; // All our subchannels. OrphanablePtr subchannel_list_; // Latest pending subchannel list. @@ -167,18 +171,7 @@ void PickFirst::ExitIdleLocked() { if (shutdown_) return; if (idle_) { idle_ = false; - if (subchannel_list_ == nullptr || - subchannel_list_->num_subchannels() == 0) { - grpc_error* error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No addresses to connect to"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - UniquePtr(New(error))); - } else { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); - } + AttemptToConnectUsingLatestUpdateArgsLocked(); } } @@ -189,36 +182,26 @@ void PickFirst::ResetBackoffLocked() { } } -void PickFirst::UpdateLocked(UpdateArgs args) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { - gpr_log(GPR_INFO, - "Pick First %p received update with %" PRIuPTR " addresses", this, - args.addresses.size()); - } - grpc_arg new_arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(args.args, &new_arg, 1); +void PickFirst::AttemptToConnectUsingLatestUpdateArgsLocked() { + // Create a subchannel list from the latest_update_args_. auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); - grpc_channel_args_destroy(new_args); + this, &grpc_lb_pick_first_trace, latest_update_args_.addresses, + combiner(), *latest_update_args_.args); + // Empty update or no valid subchannels. if (subchannel_list->num_subchannels() == 0) { - // Empty update or no valid subchannels. Unsubscribe from all current - // subchannels. + // Unsubscribe from all current subchannels. subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; // If not idle, put the channel in TRANSIENT_FAILURE. // (If we are idle, then this will happen in ExitIdleLocked() if we // haven't gotten a non-empty update by the time the application tries // to start a new call.) - if (!idle_) { - grpc_error* error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - UniquePtr(New(error))); - } + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + UniquePtr(New(error))); return; } // If one of the subchannels in the new list is already in state @@ -226,8 +209,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // currently selected subchannel is also present in the update. It // can also happen if one of the subchannels in the update is already // in the global subchannel pool because it's in use by another channel. - // TODO(roth): If we're in IDLE state, we should probably defer this - // check and instead do it in ExitIdleLocked(). for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { PickFirstSubchannelData* sd = subchannel_list->subchannel(i); grpc_connectivity_state state = sd->CheckConnectivityStateLocked(); @@ -239,10 +220,6 @@ void PickFirst::UpdateLocked(UpdateArgs args) { // not have contained the currently selected subchannel), drop // it, so that it doesn't override what we've done here. latest_pending_subchannel_list_.reset(); - // Make sure that subsequent calls to ExitIdleLocked() don't cause - // us to start watching a subchannel other than the one we've - // selected. - idle_ = false; return; } } @@ -252,13 +229,11 @@ void PickFirst::UpdateLocked(UpdateArgs args) { subchannel_list_ = std::move(subchannel_list); // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (!idle_) { - // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() - // here, since we've already checked the initial connectivity - // state of all subchannels above. - subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); - subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); - } + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. + subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0)->subchannel()->AttemptToConnect(); } else { // We do have a selected subchannel (which means it's READY), so keep // using it until one of the subchannels in the new list reports READY. @@ -274,16 +249,35 @@ void PickFirst::UpdateLocked(UpdateArgs args) { latest_pending_subchannel_list_ = std::move(subchannel_list); // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (!idle_) { - // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() - // here, since we've already checked the initial connectivity - // state of all subchannels above. - latest_pending_subchannel_list_->subchannel(0) - ->StartConnectivityWatchLocked(); - latest_pending_subchannel_list_->subchannel(0) - ->subchannel() - ->AttemptToConnect(); - } + // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() + // here, since we've already checked the initial connectivity + // state of all subchannels above. + latest_pending_subchannel_list_->subchannel(0) + ->StartConnectivityWatchLocked(); + latest_pending_subchannel_list_->subchannel(0) + ->subchannel() + ->AttemptToConnect(); + } +} + +void PickFirst::UpdateLocked(UpdateArgs args) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { + gpr_log(GPR_INFO, + "Pick First %p received update with %" PRIuPTR " addresses", this, + args.addresses.size()); + } + // Update the latest_update_args_ + grpc_arg new_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + const grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args.args, &new_arg, 1); + GPR_SWAP(const grpc_channel_args*, new_args, args.args); + grpc_channel_args_destroy(new_args); + latest_update_args_ = std::move(args); + // If we are not in idle, start connection attempt immediately. + // Otherwise, we defer the attempt into ExitIdleLocked(). + if (!idle_) { + AttemptToConnectUsingLatestUpdateArgsLocked(); } } @@ -338,10 +332,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // also set the channel state to IDLE. The reason is that if the new // state is TRANSIENT_FAILURE due to a GOAWAY reception we don't want // to connect to the re-resolved backends until we leave IDLE state. + // TODO(qianchengz): We may want to request re-resolution in + // ExitIdleLocked(). p->idle_ = true; p->channel_control_helper()->RequestReresolution(); p->selected_ = nullptr; - CancelConnectivityWatchLocked("selected subchannel failed; going IDLE"); + p->subchannel_list_.reset(); p->channel_control_helper()->UpdateState( GRPC_CHANNEL_IDLE, UniquePtr(New( p->Ref(DEBUG_LOCATION, "QueuePicker")))); @@ -454,6 +450,11 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_pick_first_trace)) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } + for (size_t i = 0; i < subchannel_list()->num_subchannels(); ++i) { + if (i != Index()) { + subchannel_list()->subchannel(i)->ShutdownLocked(); + } + } } void PickFirst::PickFirstSubchannelData:: From 9aa48c6d1c02884ef27c2976d04596bd197eb5e5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Sun, 9 Jun 2019 20:42:05 -0700 Subject: [PATCH 404/676] Drop support for ruby < 2.3; update and unskip distrib tests --- Rakefile | 4 +- grpc.gemspec | 2 +- templates/grpc.gemspec.template | 2 +- .../distribtest/ruby_centos6_x64/Dockerfile | 10 ++--- .../distribtest/ruby_centos7_x64/Dockerfile | 10 ++--- .../distribtest/ruby_fedora20_x64/Dockerfile | 10 ++--- .../distribtest/ruby_fedora21_x64/Dockerfile | 10 ++--- .../ruby_jessie_x64_ruby_2_2/Dockerfile | 40 ------------------- .../artifacts/distribtest_targets.py | 14 +++---- 9 files changed, 30 insertions(+), 72 deletions(-) delete mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile diff --git a/Rakefile b/Rakefile index d604f7935b1..8123dc541dc 100755 --- a/Rakefile +++ b/Rakefile @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/grpc.gemspec b/grpc.gemspec index fc90a350d64..11469a3ec5c 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index f8dd0938936..12862c82b29 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -15,7 +15,7 @@ s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index b53ffc22d4f..f823d0f7706 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -22,15 +22,15 @@ RUN yum install -y tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 72235bfba7f..c54f9565639 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -20,13 +20,13 @@ RUN yum update && yum install -y curl tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 3d688a889f0..f8e383bf577 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -21,15 +21,15 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index 8044adf15dc..58500c5b35d 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -26,13 +26,13 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile deleted file mode 100644 index 337fc3b5d8e..00000000000 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM debian:jessie - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - curl \ - gcc && apt-get clean - -#================== -# Ruby dependencies - -# Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB -RUN \curl -sSL https://get.rvm.io | bash -s stable - -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" -RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" -RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 1e861029faa..35a561ea928 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -340,14 +340,12 @@ def targets(): RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), - # TODO(apolcyn): unskip these after upgrading the ruby versions - # of these dockerfiles to >= 2.3. - # RubyDistribTest('linux', 'x64', 'centos6'), - # RubyDistribTest('linux', 'x64', 'centos7'), - # RubyDistribTest('linux', 'x64', 'fedora20'), - # RubyDistribTest('linux', 'x64', 'fedora21'), - # RubyDistribTest('linux', 'x64', 'fedora22'), - # RubyDistribTest('linux', 'x64', 'fedora23'), + RubyDistribTest('linux', 'x64', 'centos6'), + RubyDistribTest('linux', 'x64', 'centos7'), + RubyDistribTest('linux', 'x64', 'fedora20'), + RubyDistribTest('linux', 'x64', 'fedora21'), + RubyDistribTest('linux', 'x64', 'fedora22'), + RubyDistribTest('linux', 'x64', 'fedora23'), RubyDistribTest('linux', 'x64', 'opensuse'), RubyDistribTest('linux', 'x64', 'ubuntu1204'), RubyDistribTest('linux', 'x64', 'ubuntu1404'), From 9e2bb81512af90d24c592e4c905f9f1a0aa0a5f3 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Thu, 20 Jun 2019 12:53:30 +0200 Subject: [PATCH 405/676] Roll Dart to 2.3 --- .../interoptest/grpc_interop_dart/Dockerfile.template | 2 +- tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template index 34ea645cfa0..dee59335280 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM google/dart:2.0 + FROM google/dart:2.3 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart diff --git a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile index 897354891c1..43d8a60daea 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM google/dart:2.0 +FROM google/dart:2.3 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart From c5c3983c974e92930dbae384f2c2bcf8655545a8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Jun 2019 09:08:29 -0700 Subject: [PATCH 406/676] Fix hard written port --- src/objective-c/tests/UnitTests/GRPCClientTests.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/UnitTests/GRPCClientTests.m b/src/objective-c/tests/UnitTests/GRPCClientTests.m index 94164164c28..bcd87c17b78 100644 --- a/src/objective-c/tests/UnitTests/GRPCClientTests.m +++ b/src/objective-c/tests/UnitTests/GRPCClientTests.m @@ -37,10 +37,14 @@ #define TEST_TIMEOUT 16 -static NSString *const kHostAddress = @"localhost:5050"; +// The server address is derived from preprocessor macro, which is +// in turn derived from environment variable of the same name. +#define NSStringize_helper(x) #x +#define NSStringize(x) @NSStringize_helper(x) +static NSString *const kHostAddress = NSStringize(HOST_PORT_LOCAL); static NSString *const kPackage = @"grpc.testing"; static NSString *const kService = @"TestService"; -static NSString *const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com"; +static NSString *const kRemoteSSLHost = NSStringize(HOST_PORT_REMOTE); static GRPCProtoMethod *kInexistentMethod; static GRPCProtoMethod *kEmptyCallMethod; From 04d504f67f6f2410482eaedbfff8798465f3febc Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 09:45:27 -0700 Subject: [PATCH 407/676] Fix delete operator undefined reference error for interface --- src/core/lib/iomgr/executor/mpmcqueue.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 39396eeaad0..aec8dd33c60 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -48,6 +48,8 @@ class MPMCQueueInterface { // Return number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS }; class MPMCQueue : public MPMCQueueInterface { From 49f0fb9035120d0f5b5fa49846324c0b2d59c257 Mon Sep 17 00:00:00 2001 From: Marcel Hlopko Date: Thu, 20 Jun 2019 18:55:56 +0200 Subject: [PATCH 408/676] Migrate from dep.proto to dep[ProtoInfo] --- WORKSPACE | 2 +- bazel/generate_cc.bzl | 4 ++-- bazel/python_rules.bzl | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 2db3c5db2ff..60582d1a0f5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -20,7 +20,7 @@ register_toolchains( git_repository( name = "io_bazel_rules_python", - commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", + commit = "fdbb17a4118a1728d19e638a5291b4c4266ea5b8", remote = "https://github.com/bazelbuild/rules_python.git", ) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index b7edcda702f..581165a190a 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -41,11 +41,11 @@ def _join_directories(directories): def generate_cc_impl(ctx): """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.check_deps_sources.to_list()] + protos = [f for src in ctx.attr.srcs for f in src[ProtoInfo].check_deps_sources.to_list()] includes = [ f for src in ctx.attr.srcs - for f in src.proto.transitive_imports.to_list() + for f in src[ProtoInfo].transitive_imports.to_list() ] outs = [] proto_root = get_proto_root( diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl index 17004f3474d..3df30f82628 100644 --- a/bazel/python_rules.bzl +++ b/bazel/python_rules.bzl @@ -28,12 +28,12 @@ def _get_staged_proto_file(context, source_file): def _generate_py_impl(context): protos = [] for src in context.attr.deps: - for file in src.proto.direct_sources: + for file in src[ProtoInfo].direct_sources: protos.append(_get_staged_proto_file(context, file)) includes = [ file for src in context.attr.deps - for file in src.proto.transitive_imports.to_list() + for file in src[ProtoInfo].transitive_imports.to_list() ] proto_root = get_proto_root(context.label.workspace_root) format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) From ecf04ccf4d8be9378166ec9e0ccf44081e211d11 Mon Sep 17 00:00:00 2001 From: Marcel Hlopko Date: Thu, 20 Jun 2019 18:57:33 +0200 Subject: [PATCH 409/676] Require ProtoInfo in attributes, not "proto" --- bazel/generate_cc.bzl | 2 +- bazel/python_rules.bzl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 581165a190a..87e8b9d3292 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -146,7 +146,7 @@ _generate_cc = rule( "srcs": attr.label_list( mandatory = True, allow_empty = False, - providers = ["proto"], + providers = [ProtoInfo], ), "plugin": attr.label( executable = True, diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl index 3df30f82628..d4ff77094cc 100644 --- a/bazel/python_rules.bzl +++ b/bazel/python_rules.bzl @@ -99,7 +99,7 @@ __generate_py = rule( "deps": attr.label_list( mandatory = True, allow_empty = False, - providers = ["proto"], + providers = [ProtoInfo], ), "plugin": attr.label( executable = True, From 7eb8bac69612b1e5a73248eba64532ff38e8e758 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Jun 2019 10:03:01 -0700 Subject: [PATCH 410/676] Resolve xcodebuild issue on Mac --- src/objective-c/tests/run_one_test.sh | 10 +++++++++- tools/run_tests/run_tests.py | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh index 342d5a5b38d..624ad4743eb 100755 --- a/src/objective-c/tests/run_one_test.sh +++ b/src/objective-c/tests/run_one_test.sh @@ -45,10 +45,18 @@ set -o pipefail XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )' +if [ $PLATFORM == ios ]; then +DESTINATION="name='iPhone 8'" +elif [ $PLATFORM == macos ]; then +DESTINATION='platform=macOS' +else +DESTINATION="name='iPhone 8'" +fi + xcodebuild \ -workspace Tests.xcworkspace \ -scheme $SCHEME \ - -destination name="iPhone 8" \ + -destination "$DESTINATION" \ HOST_PORT_LOCALSSL=localhost:$TLS_PORT \ HOST_PORT_LOCAL=localhost:$PLAIN_PORT \ HOST_PORT_REMOTE=grpc-test.sandbox.googleapis.com \ diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 0addc093d73..f11927bd5d6 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1137,7 +1137,8 @@ class ObjCLanguage(object): shortname='mac-test-basictests', cpu_cost=1e6, environ={ - 'SCHEME': 'MacTests' + 'SCHEME': 'MacTests', + 'PLATFORM': 'macos' })) return sorted(out) From cc18abfa54e00a39fcc29763da508e12c5095ed5 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 20 Jun 2019 17:08:15 +0000 Subject: [PATCH 411/676] Pin bundler where needed --- tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index f823d0f7706..0812b860d7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -30,7 +30,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index c54f9565639..fc4eabbbb15 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -26,7 +26,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index f8e383bf577..73a4bd76c88 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -29,7 +29,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index 58500c5b35d..43c0ae5d8d6 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -32,7 +32,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins From 07728ed01c170c1d4843357c1eca32e5d44323e4 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Jun 2019 12:46:00 -0700 Subject: [PATCH 412/676] Fix ios simulator failure --- src/objective-c/tests/run_one_test.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/objective-c/tests/run_one_test.sh b/src/objective-c/tests/run_one_test.sh index 624ad4743eb..b74107e4a66 100755 --- a/src/objective-c/tests/run_one_test.sh +++ b/src/objective-c/tests/run_one_test.sh @@ -45,12 +45,12 @@ set -o pipefail XCODEBUILD_FILTER='(^CompileC |^Ld |^ *[^ ]*clang |^ *cd |^ *export |^Libtool |^ *[^ ]*libtool |^CpHeader |^ *builtin-copy )' -if [ $PLATFORM == ios ]; then -DESTINATION="name='iPhone 8'" +if [ -z $PLATFORM ]; then +DESTINATION='name=iPhone 8' +elif [ $PLATFORM == ios ]; then +DESTINATION='name=iPhone 8' elif [ $PLATFORM == macos ]; then DESTINATION='platform=macOS' -else -DESTINATION="name='iPhone 8'" fi xcodebuild \ From 9c5ed4550a3d1ed905cc61c2bab5cd9719d22647 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 20 Jun 2019 19:56:09 +0000 Subject: [PATCH 413/676] Also updated fedora 2.2 and 2.3 dockerfiles --- .../distribtest/ruby_fedora22_x64/Dockerfile | 24 +++++++++++++++++-- .../distribtest/ruby_fedora23_x64/Dockerfile | 24 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile index 848c5be789a..e077f68a38d 100644 --- a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:22 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile index 47dd577e217..f586ae377a3 100644 --- a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:23 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" From cb8730c71dbf791331f46d5674be802b436b4e61 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 14:00:05 -0700 Subject: [PATCH 414/676] Modify as static var --- src/core/lib/gprpp/thd_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index e26ee507a3d..a26630a3dc3 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -50,7 +50,7 @@ struct thd_arg { }; size_t RoundUpToPageSize(size_t size) { - size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); + static size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); return (size + page_size - 1) & ~(page_size - 1); } From 30c700fd02a43c7540130370812e14ff0afab294 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Sun, 9 Jun 2019 20:42:05 -0700 Subject: [PATCH 415/676] Drop support for ruby < 2.3; update and unskip distrib tests --- Rakefile | 4 +- grpc.gemspec | 2 +- templates/grpc.gemspec.template | 2 +- .../distribtest/ruby_centos6_x64/Dockerfile | 10 ++--- .../distribtest/ruby_centos7_x64/Dockerfile | 10 ++--- .../distribtest/ruby_fedora20_x64/Dockerfile | 10 ++--- .../distribtest/ruby_fedora21_x64/Dockerfile | 10 ++--- .../ruby_jessie_x64_ruby_2_2/Dockerfile | 40 ------------------- .../artifacts/distribtest_targets.py | 14 +++---- 9 files changed, 30 insertions(+), 72 deletions(-) delete mode 100644 tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile diff --git a/Rakefile b/Rakefile index d604f7935b1..8123dc541dc 100755 --- a/Rakefile +++ b/Rakefile @@ -124,10 +124,10 @@ task 'gem:native' do "invoked on macos with ruby #{RUBY_VERSION}. The ruby macos artifact " \ "build should be running on ruby 2.5." end - system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" else Rake::Task['dlls'].execute - docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0:2.2.2 V=#{verbose} GRPC_CONFIG=#{grpc_config}" + docker_for_windows "gem update --system --no-document && bundle && rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}" end end diff --git a/grpc.gemspec b/grpc.gemspec index fc90a350d64..11469a3ec5c 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |s| s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index f8dd0938936..12862c82b29 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -15,7 +15,7 @@ s.description = 'Send RPCs from Ruby using GRPC' s.license = 'Apache-2.0' - s.required_ruby_version = '>= 2.0.0' + s.required_ruby_version = '>= 2.3.0' s.files = %w( Makefile .yardopts ) s.files += %w( etc/roots.pem ) diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index b53ffc22d4f..f823d0f7706 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -22,15 +22,15 @@ RUN yum install -y tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index 72235bfba7f..c54f9565639 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -20,13 +20,13 @@ RUN yum update && yum install -y curl tar which RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index 3d688a889f0..f8e383bf577 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -21,15 +21,15 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 +# Install Ruby 2.3 # Running the installation twice to work around docker issue when using overlay. # https://github.com/docker/docker/issues/10180 -RUN (/bin/bash -l -c "rvm install ruby-2.2.10") || (/bin/bash -l -c "rvm install ruby-2.2.10") -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8") +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index 8044adf15dc..58500c5b35d 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -26,13 +26,13 @@ RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y opens RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB RUN curl -sSL https://get.rvm.io | bash -s stable -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile b/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile deleted file mode 100644 index 337fc3b5d8e..00000000000 --- a/tools/dockerfile/distribtest/ruby_jessie_x64_ruby_2_2/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2015 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM debian:jessie - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - curl \ - gcc && apt-get clean - -#================== -# Ruby dependencies - -# Install rvm -RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB -RUN \curl -sSL https://get.rvm.io | bash -s stable - -# Install Ruby 2.2 -RUN /bin/bash -l -c "rvm install ruby-2.2.10" -RUN /bin/bash -l -c "rvm use --default ruby-2.2.10" -RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" -RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" -RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.2.10' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/run_tests/artifacts/distribtest_targets.py b/tools/run_tests/artifacts/distribtest_targets.py index 1e861029faa..35a561ea928 100644 --- a/tools/run_tests/artifacts/distribtest_targets.py +++ b/tools/run_tests/artifacts/distribtest_targets.py @@ -340,14 +340,12 @@ def targets(): RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_4'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'), RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'), - # TODO(apolcyn): unskip these after upgrading the ruby versions - # of these dockerfiles to >= 2.3. - # RubyDistribTest('linux', 'x64', 'centos6'), - # RubyDistribTest('linux', 'x64', 'centos7'), - # RubyDistribTest('linux', 'x64', 'fedora20'), - # RubyDistribTest('linux', 'x64', 'fedora21'), - # RubyDistribTest('linux', 'x64', 'fedora22'), - # RubyDistribTest('linux', 'x64', 'fedora23'), + RubyDistribTest('linux', 'x64', 'centos6'), + RubyDistribTest('linux', 'x64', 'centos7'), + RubyDistribTest('linux', 'x64', 'fedora20'), + RubyDistribTest('linux', 'x64', 'fedora21'), + RubyDistribTest('linux', 'x64', 'fedora22'), + RubyDistribTest('linux', 'x64', 'fedora23'), RubyDistribTest('linux', 'x64', 'opensuse'), RubyDistribTest('linux', 'x64', 'ubuntu1204'), RubyDistribTest('linux', 'x64', 'ubuntu1404'), From 7361c440c548e65238251cb0f5535d3e65104be1 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 20 Jun 2019 17:08:15 +0000 Subject: [PATCH 416/676] Pin bundler where needed --- tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile | 2 +- tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile index f823d0f7706..0812b860d7f 100644 --- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile @@ -30,7 +30,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile index c54f9565639..fc4eabbbb15 100644 --- a/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_centos7_x64/Dockerfile @@ -26,7 +26,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile index f8e383bf577..73a4bd76c88 100644 --- a/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora20_x64/Dockerfile @@ -29,7 +29,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile index 58500c5b35d..43c0ae5d8d6 100644 --- a/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora21_x64/Dockerfile @@ -32,7 +32,7 @@ RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" -RUN /bin/bash -l -c "gem install bundler --no-document" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" RUN mkdir /var/local/jenkins From 1a0eb8bea6ec7939582c87c4ba0d7bae24ab4a52 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 20 Jun 2019 19:56:09 +0000 Subject: [PATCH 417/676] Also updated fedora 2.2 and 2.3 dockerfiles --- .../distribtest/ruby_fedora22_x64/Dockerfile | 24 +++++++++++++++++-- .../distribtest/ruby_fedora23_x64/Dockerfile | 24 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile index 848c5be789a..e077f68a38d 100644 --- a/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora22_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:22 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" diff --git a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile index 47dd577e217..f586ae377a3 100644 --- a/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile +++ b/tools/dockerfile/distribtest/ruby_fedora23_x64/Dockerfile @@ -14,6 +14,26 @@ FROM fedora:23 -RUN yum clean all && yum update -y && yum install -y ruby findutils +# Make yum work properly under docker when using overlay storage driver. +# https://bugzilla.redhat.com/show_bug.cgi?id=1213602#c9 +# https://github.com/docker/docker/issues/10180 +RUN yum install -y yum-plugin-ovl -RUN gem install bundler +# distro-sync and install openssl, per https://github.com/fedora-cloud/docker-brew-fedora/issues/19 +RUN yum clean all && yum update -y && yum distro-sync -y && yum install -y openssl gnupg which findutils tar procps + +# Install rvm +RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +RUN curl -sSL https://get.rvm.io | bash -s stable + +# Install Ruby 2.3 +RUN /bin/bash -l -c "rvm install ruby-2.3.8" +RUN /bin/bash -l -c "rvm use --default ruby-2.3.8" +RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc" +RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" +RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc" +RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document" + +RUN mkdir /var/local/jenkins + +RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc" From 72fe202369e2910cee3fbe4995949c48378863e0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Jun 2019 09:48:45 -0700 Subject: [PATCH 418/676] Update Protobuf version --- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/!ProtoCompiler.podspec | 2 +- .../src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index e9b5645d012..939078def22 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -101,7 +101,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 58d74be4d4e..d8ce4d8e89d 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.7.0' + v = '3.8.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 741f9b7e54d..b2335ac8a9e 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -103,7 +103,7 @@ s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.7.0' + s.dependency '!ProtoCompiler', '3.8.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' From 233eee421fe2b1bea41e1e844ec1d1424d3c7c5b Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 14:49:04 -0700 Subject: [PATCH 419/676] Modify static var to global var in file --- src/core/lib/gprpp/thd_posix.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index a26630a3dc3..fb732b4d9f0 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -49,8 +49,9 @@ struct thd_arg { bool tracked; }; +size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); + size_t RoundUpToPageSize(size_t size) { - static size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); return (size + page_size - 1) & ~(page_size - 1); } From 1c8894d9c440340e6c1ed4169e70c677f782e44c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 21 Jun 2019 00:33:06 +0200 Subject: [PATCH 420/676] Hail mary. --- tools/bazel.rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/bazel.rc b/tools/bazel.rc index 6378b82017e..4bd3a5d7445 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -51,6 +51,10 @@ build:ubsan --copt=-DUNDEFINED_BEHAVIOR_SANITIZER # used by absl build:ubsan --copt=-fno-sanitize=function,vptr build:ubsan --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt +# For some reasons, these two stopped being propagated, so, redeclaring them here. +# That's a hack that needs to be removed once we understand what's going on. +build:ubsan --copt=-DPB_FIELD_32BIT=1 +build:ubsan --copt=-DGRPC_PORT_ISOLATED_RUNTIME=1 build:basicprof --strip=never build:basicprof --copt=-DNDEBUG From 7c4c6e2e9a9882083ae1814b6b3040fa65c24113 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 17:07:34 -0700 Subject: [PATCH 421/676] Modify page_size as const var --- src/core/lib/gprpp/thd_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index fb732b4d9f0..dbb9c82cb06 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -49,7 +49,7 @@ struct thd_arg { bool tracked; }; -size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); +const size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); size_t RoundUpToPageSize(size_t size) { return (size + page_size - 1) & ~(page_size - 1); From fbfb93c88fead0bd62cc20d800bdcf45cf514caa Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 18 Jun 2019 17:50:28 -0700 Subject: [PATCH 422/676] Fix C++ tests to run on iOS - Define grpc_iomgr_run_in_background in iomgr_posix_cfstream.cc - Use *_IF_SUPPORTED() for death tests - Move global test init, teardown to SetUpTestCase, TearDownTestCase as GTMGoogleTestRun doesn't run main() --- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 2 + test/cpp/codegen/proto_utils_test.cc | 49 +++++++++++++------ test/cpp/common/channel_arguments_test.cc | 6 ++- test/cpp/end2end/client_lb_end2end_test.cc | 9 ++-- test/cpp/end2end/filter_end2end_test.cc | 12 ++--- test/cpp/end2end/grpclb_end2end_test.cc | 16 +++--- .../end2end/service_config_end2end_test.cc | 9 ++-- test/cpp/end2end/xds_end2end_test.cc | 16 +++--- test/cpp/grpclb/grpclb_api_test.cc | 9 ++-- test/cpp/naming/cancel_ares_query_test.cc | 49 ++++++++++++------- test/cpp/server/server_builder_test.cc | 18 ++++--- ...server_builder_with_socket_mutator_test.cc | 11 +++-- test/cpp/util/byte_buffer_test.cc | 9 ++-- test/cpp/util/slice_test.cc | 6 ++- 14 files changed, 145 insertions(+), 76 deletions(-) diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index cf4d05318ea..c086ba52396 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -90,4 +90,6 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { return false; } + #endif /* GRPC_CFSTREAM_IOMGR */ diff --git a/test/cpp/codegen/proto_utils_test.cc b/test/cpp/codegen/proto_utils_test.cc index 801660eef67..e9dcea0fd9c 100644 --- a/test/cpp/codegen/proto_utils_test.cc +++ b/test/cpp/codegen/proto_utils_test.cc @@ -49,7 +49,18 @@ class GrpcByteBufferPeer { ByteBuffer* bb_; }; -class ProtoUtilsTest : public ::testing::Test {}; +class ProtoUtilsTest : public ::testing::Test { + protected: + static void SetUpTestCase() { + // Ensure the ProtoBufferWriter internals are initialized. + grpc::internal::GrpcLibraryInitializer init; + init.summon(); + grpc::GrpcLibraryCodegen lib; + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } +}; // Regression test for a memory corruption bug where a series of // ProtoBufferWriter Next()/Backup() invocations could result in a dangling @@ -136,36 +147,46 @@ void BufferWriterTest(int block_size, int total_size, int backup_size) { grpc_byte_buffer_reader_destroy(&reader); } -TEST(WriterTest, TinyBlockTinyBackup) { +class WriterTest : public ::testing::Test { + protected: + static void SetUpTestCase() { + grpc::internal::GrpcLibraryInitializer init; + init.summon(); + grpc::GrpcLibraryCodegen lib; + // Ensure the ProtoBufferWriter internals are initialized. + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } +}; + +TEST_F(WriterTest, TinyBlockTinyBackup) { for (int i = 2; i < static_cast GRPC_SLICE_INLINED_SIZE; i++) { BufferWriterTest(i, 256, 1); } } -TEST(WriterTest, SmallBlockTinyBackup) { BufferWriterTest(64, 256, 1); } +TEST_F(WriterTest, SmallBlockTinyBackup) { BufferWriterTest(64, 256, 1); } -TEST(WriterTest, SmallBlockNoBackup) { BufferWriterTest(64, 256, 0); } +TEST_F(WriterTest, SmallBlockNoBackup) { BufferWriterTest(64, 256, 0); } -TEST(WriterTest, SmallBlockFullBackup) { BufferWriterTest(64, 256, 64); } +TEST_F(WriterTest, SmallBlockFullBackup) { BufferWriterTest(64, 256, 64); } -TEST(WriterTest, LargeBlockTinyBackup) { BufferWriterTest(4096, 8192, 1); } +TEST_F(WriterTest, LargeBlockTinyBackup) { BufferWriterTest(4096, 8192, 1); } -TEST(WriterTest, LargeBlockNoBackup) { BufferWriterTest(4096, 8192, 0); } +TEST_F(WriterTest, LargeBlockNoBackup) { BufferWriterTest(4096, 8192, 0); } -TEST(WriterTest, LargeBlockFullBackup) { BufferWriterTest(4096, 8192, 4096); } +TEST_F(WriterTest, LargeBlockFullBackup) { BufferWriterTest(4096, 8192, 4096); } -TEST(WriterTest, LargeBlockLargeBackup) { BufferWriterTest(4096, 8192, 4095); } +TEST_F(WriterTest, LargeBlockLargeBackup) { + BufferWriterTest(4096, 8192, 4095); +} } // namespace } // namespace internal } // namespace grpc int main(int argc, char** argv) { - // Ensure the ProtoBufferWriter internals are initialized. - grpc::internal::GrpcLibraryInitializer init; - init.summon(); - grpc::GrpcLibraryCodegen lib; - ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc index 12fd9784f47..7fbed5ba3ea 100644 --- a/test/cpp/common/channel_arguments_test.cc +++ b/test/cpp/common/channel_arguments_test.cc @@ -84,6 +84,10 @@ class ChannelArgumentsTest : public ::testing::Test { channel_args.SetChannelArgs(args); } + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } + grpc::string GetDefaultUserAgentPrefix() { std::ostringstream user_agent_prefix; user_agent_prefix << "grpc-c++/" << Version(); @@ -252,8 +256,6 @@ TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index f6d4a48b6f0..d499f136ef6 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -141,6 +141,12 @@ class ClientLbEnd2endTest : public ::testing::Test { creds_(new SecureChannelCredentials( grpc_fake_transport_security_credentials_create())) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + void SetUp() override { grpc_init(); response_generator_ = @@ -1481,9 +1487,6 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index a4c981a3eb1..e96825c33eb 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -121,6 +121,12 @@ class FilterEnd2endTest : public ::testing::Test { protected: FilterEnd2endTest() : server_host_("localhost") {} + static void SetUpTestCase() { + gpr_log(GPR_ERROR, "In SetUpTestCase"); + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); + } + void SetUp() override { int port = grpc_pick_unused_port_or_die(); server_address_ << server_host_ << ":" << port; @@ -321,11 +327,6 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { EXPECT_EQ(1, GetConnectionCounterValue()); } -void RegisterFilter() { - grpc::RegisterChannelFilter( - "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); -} - } // namespace } // namespace testing } // namespace grpc @@ -333,6 +334,5 @@ void RegisterFilter() { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - grpc::testing::RegisterFilter(); return RUN_ALL_TESTS(); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 70c443412aa..e3b79c810cd 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -374,6 +374,15 @@ class GrpclbEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } + void SetUp() override { response_generator_ = grpc_core::MakeRefCounted(); @@ -1003,7 +1012,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; // Make sure that we blow up (via abort() from the security connector) when // the name from the balancer doesn't match expectations. - ASSERT_DEATH( + ASSERT_DEATH_IF_SUPPORTED( { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({AddressData{balancers_[0]->port_, true, "woops"}}); @@ -1990,13 +1999,8 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); return result; } diff --git a/test/cpp/end2end/service_config_end2end_test.cc b/test/cpp/end2end/service_config_end2end_test.cc index 8bf4a7c22ff..a00a45ecbb7 100644 --- a/test/cpp/end2end/service_config_end2end_test.cc +++ b/test/cpp/end2end/service_config_end2end_test.cc @@ -119,6 +119,12 @@ class ServiceConfigEnd2endTest : public ::testing::Test { creds_(new SecureChannelCredentials( grpc_fake_transport_security_credentials_create())) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + void SetUp() override { grpc_init(); response_generator_ = @@ -611,9 +617,6 @@ TEST_F(ServiceConfigEnd2endTest, } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); const auto result = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index eac6f32a538..5e7717e4e06 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -370,6 +370,15 @@ class XdsEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds) {} + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } + void SetUp() override { response_generator_ = grpc_core::MakeRefCounted(); @@ -788,7 +797,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; // Make sure that we blow up (via abort() from the security connector) when // the name from the balancer doesn't match expectations. - ASSERT_DEATH( + ASSERT_DEATH_IF_SUPPORTED( { ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({}, @@ -1401,13 +1410,8 @@ class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { } // namespace grpc int main(int argc, char** argv) { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - grpc_init(); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); return result; } diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index ecba9f9ca3c..0ace512c278 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -31,7 +31,12 @@ namespace { using grpc::lb::v1::LoadBalanceRequest; using grpc::lb::v1::LoadBalanceResponse; -class GrpclbTest : public ::testing::Test {}; +class GrpclbTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; grpc::string Ip4ToPackedString(const char* ip_str) { struct in_addr ip4; @@ -128,8 +133,6 @@ TEST_F(GrpclbTest, ParseResponseServerList) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 667011ae291..9d4390f63d2 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -177,7 +177,32 @@ void TestCancelActiveDNSQuery(ArgsStruct* args) { ArgsFinish(args); } -TEST(CancelDuringAresQuery, TestCancelActiveDNSQuery) { +class CancelDuringAresQuery : public ::testing::Test { + protected: + static void SetUpTestCase() { + GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); + // Sanity check the time that it takes to run the test + // including the teardown time (the teardown + // part of the test involves cancelling the DNS query, + // which is the main point of interest for this test). + overall_deadline = grpc_timeout_seconds_to_deadline(4); + grpc_init(); + } + + static void TearDownTestCase() { + grpc_shutdown(); + if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), overall_deadline) > 0) { + gpr_log(GPR_ERROR, "Test took too long"); + abort(); + } + } + + private: + static gpr_timespec overall_deadline; +}; +gpr_timespec CancelDuringAresQuery::overall_deadline; + +TEST_F(CancelDuringAresQuery, TestCancelActiveDNSQuery) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); @@ -216,7 +241,7 @@ void MaybePollArbitraryPollsetTwice() {} #endif -TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { +TEST_F(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); @@ -352,18 +377,18 @@ void TestCancelDuringActiveQuery( EndTest(client, cq); } -TEST(CancelDuringAresQuery, - TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { +TEST_F(CancelDuringAresQuery, + TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) { TestCancelDuringActiveQuery(NONE /* don't set query timeouts */); } -TEST( +TEST_F( CancelDuringAresQuery, TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) { TestCancelDuringActiveQuery(SHORT /* set short query timeout */); } -TEST( +TEST_F( CancelDuringAresQuery, TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) { TestCancelDuringActiveQuery(ZERO /* disable query timeouts */); @@ -374,18 +399,6 @@ TEST( int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); - GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares"); - // Sanity check the time that it takes to run the test - // including the teardown time (the teardown - // part of the test involves cancelling the DNS query, - // which is the main point of interest for this test). - gpr_timespec overall_deadline = grpc_timeout_seconds_to_deadline(4); - grpc_init(); auto result = RUN_ALL_TESTS(); - grpc_shutdown(); - if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), overall_deadline) > 0) { - gpr_log(GPR_ERROR, "Test took too long"); - abort(); - } return result; } diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc index 5c22dda16f0..e07ae8dbc66 100644 --- a/test/cpp/server/server_builder_test.cc +++ b/test/cpp/server/server_builder_test.cc @@ -44,13 +44,19 @@ const grpc::string& GetPort() { return g_port; } -TEST(ServerBuilderTest, NoOp) { ServerBuilder b; } +class ServerBuilderTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } -TEST(ServerBuilderTest, CreateServerNoPorts) { + static void TearDownTestCase() { grpc_shutdown(); } +}; +TEST_F(ServerBuilderTest, NoOp) { ServerBuilder b; } + +TEST_F(ServerBuilderTest, CreateServerNoPorts) { ServerBuilder().RegisterService(&g_service).BuildAndStart()->Shutdown(); } -TEST(ServerBuilderTest, CreateServerOnePort) { +TEST_F(ServerBuilderTest, CreateServerOnePort) { ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -58,7 +64,7 @@ TEST(ServerBuilderTest, CreateServerOnePort) { ->Shutdown(); } -TEST(ServerBuilderTest, CreateServerRepeatedPort) { +TEST_F(ServerBuilderTest, CreateServerRepeatedPort) { ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -67,7 +73,7 @@ TEST(ServerBuilderTest, CreateServerRepeatedPort) { ->Shutdown(); } -TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { +TEST_F(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { EXPECT_EQ(ServerBuilder() .RegisterService(&g_service) .AddListeningPort(GetPort(), InsecureServerCredentials()) @@ -82,8 +88,6 @@ TEST(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/server/server_builder_with_socket_mutator_test.cc b/test/cpp/server/server_builder_with_socket_mutator_test.cc index 5c7dd696c9f..15e5c073a04 100644 --- a/test/cpp/server/server_builder_with_socket_mutator_test.cc +++ b/test/cpp/server/server_builder_with_socket_mutator_test.cc @@ -86,7 +86,14 @@ class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption { MockSocketMutator* mock_socket_mutator_; }; -TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { +class ServerBuilderWithSocketMutatorTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; + +TEST_F(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die()); auto mock_socket_mutator = new MockSocketMutator(); std::unique_ptr mock_socket_mutator_builder_option( @@ -109,8 +116,6 @@ TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index 9bffbf7ac1c..fdae56a90c2 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -36,7 +36,12 @@ namespace { const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; -class ByteBufferTest : public ::testing::Test {}; +class ByteBufferTest : public ::testing::Test { + protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } +}; TEST_F(ByteBufferTest, CopyCtor) { ByteBuffer buffer1; @@ -121,8 +126,6 @@ TEST_F(ByteBufferTest, SerializationMakesCopy) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } diff --git a/test/cpp/util/slice_test.cc b/test/cpp/util/slice_test.cc index dc1910038f0..f8561c48a14 100644 --- a/test/cpp/util/slice_test.cc +++ b/test/cpp/util/slice_test.cc @@ -33,6 +33,10 @@ const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; class SliceTest : public ::testing::Test { protected: + static void SetUpTestCase() { grpc_init(); } + + static void TearDownTestCase() { grpc_shutdown(); } + void CheckSliceSize(const Slice& s, const grpc::string& content) { EXPECT_EQ(content.size(), s.size()); } @@ -132,8 +136,6 @@ TEST_F(SliceTest, Cslice) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - grpc_init(); int ret = RUN_ALL_TESTS(); - grpc_shutdown(); return ret; } From 43628b286ff94de01aaee70f6578302db45d32ec Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 19 Jun 2019 14:14:02 -0700 Subject: [PATCH 423/676] Update googletest version to v1.8.1 Bazel builds of test/cpp/end2end:end2end_test were failing on Mac OS with v1.8.0 due to missing gtest symbols. The issue is not seen in v1.8.1. A WORKSPACE file was added to gtest repo in 1.8.1, so gtest.BUILD can be removed. --- bazel/grpc_deps.bzl | 12 ++---- test/cpp/end2end/BUILD | 6 --- test/cpp/ext/filters/census/BUILD | 1 - test/cpp/naming/BUILD | 2 +- .../generate_resolver_component_tests.bzl | 4 +- test/cpp/server/load_reporter/BUILD | 1 - third_party/googletest | 2 +- third_party/gtest.BUILD | 42 ------------------- tools/run_tests/sanity/check_submodules.sh | 2 +- 9 files changed, 8 insertions(+), 64 deletions(-) delete mode 100644 third_party/gtest.BUILD diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 151825c6839..9512c25dfbe 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -66,11 +66,6 @@ def grpc_deps(): actual = "@com_github_google_googletest//:gtest", ) - native.bind( - name = "gmock", - actual = "@com_github_google_googletest//:gmock", - ) - native.bind( name = "benchmark", actual = "@com_github_google_benchmark//:benchmark", @@ -144,10 +139,9 @@ def grpc_deps(): if "com_github_google_googletest" not in native.existing_rules(): http_archive( name = "com_github_google_googletest", - build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD", - sha256 = "175a22300b3450e27e5f2e6f95cc9abca74617cbc21a1e0ed19bdfbd22ea0305", - strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", - url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz", + sha256 = "d0d447b4feeedca837a0d46a289d4223089b32ac2f84545fa4982755cc8919be", + strip_prefix = "googletest-2fe3bd994b3189899d93f1d5a881e725e046fdc2", + url = "https://github.com/google/googletest/archive/2fe3bd994b3189899d93f1d5a881e725e046fdc2.tar.gz", ) if "com_github_gflags_gflags" not in native.existing_rules(): diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d229cc33034..ab0ef0c46ba 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -369,7 +369,6 @@ grpc_cc_test( name = "mock_test", srcs = ["mock_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -406,7 +405,6 @@ grpc_cc_test( name = "client_lb_end2end_test", srcs = ["client_lb_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -427,7 +425,6 @@ grpc_cc_test( name = "service_config_end2end_test", srcs = ["service_config_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -447,7 +444,6 @@ grpc_cc_test( name = "grpclb_end2end_test", srcs = ["grpclb_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -469,7 +465,6 @@ grpc_cc_test( name = "xds_end2end_test", srcs = ["xds_end2end_test.cc"], external_deps = [ - "gmock", "gtest", ], deps = [ @@ -594,7 +589,6 @@ grpc_cc_test( srcs = ["server_load_reporting_end2end_test.cc"], external_deps = [ "gtest", - "gmock", ], deps = [ "//:grpcpp_server_load_reporting", diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 78b27e2063c..452a84b2a7a 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -26,7 +26,6 @@ grpc_cc_test( ], external_deps = [ "gtest", - "gmock", "opencensus-stats-test", ], language = "C++", diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD index 7db435a3fd4..b91c0b83c9b 100644 --- a/test/cpp/naming/BUILD +++ b/test/cpp/naming/BUILD @@ -37,7 +37,7 @@ grpc_py_binary( grpc_cc_test( name = "cancel_ares_query_test", srcs = ["cancel_ares_query_test.cc"], - external_deps = ["gmock"], + external_deps = ["gtest"], deps = [ ":dns_test_util", "//:gpr", diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index bcc62f62871..2ce61d05446 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -23,7 +23,7 @@ def generate_resolver_component_tests(): "address_sorting_test.cc", ], external_deps = [ - "gmock", + "gtest", ], deps = [ "//test/cpp/util:test_util%s" % unsecure_build_config_suffix, @@ -43,7 +43,7 @@ def generate_resolver_component_tests(): "resolver_component_test.cc", ], external_deps = [ - "gmock", + "gtest", ], deps = [ ":dns_test_util", diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index db5c93263ad..633b6d8c0d9 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -35,7 +35,6 @@ grpc_cc_test( srcs = ["load_reporter_test.cc"], external_deps = [ "gtest", - "gmock", "opencensus-stats-test", ], deps = [ diff --git a/third_party/googletest b/third_party/googletest index ec44c6c1675..2fe3bd994b3 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780 +Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2 diff --git a/third_party/gtest.BUILD b/third_party/gtest.BUILD deleted file mode 100644 index f38bfd8d457..00000000000 --- a/third_party/gtest.BUILD +++ /dev/null @@ -1,42 +0,0 @@ -cc_library( - name = "gtest", - srcs = [ - "googletest/src/gtest-all.cc", - ], - hdrs = glob([ - "googletest/include/**/*.h", - "googletest/src/*.cc", - "googletest/src/*.h", - ]), - includes = [ - "googletest", - "googletest/include", - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) - -cc_library( - name = "gmock", - srcs = [ - "googlemock/src/gmock-all.cc" - ], - hdrs = glob([ - "googlemock/include/**/*.h", - "googlemock/src/*.cc", - "googlemock/src/*.h" - ]), - includes = [ - "googlemock", - "googlemock/include", - ], - deps = [ - ":gtest", - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 487479ba3da..7b11d49655c 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -35,7 +35,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master) 28f50e0fed19872e0fd50dd23ce2ee8cd759338e third_party/gflags (v2.2.0-5-g30dbc81) 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb) - ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) + 2fe3bd994b3189899d93f1d5a881e725e046fdc2 third_party/googletest (release-1.8.1) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) 09745575a923640154bcf307fba8aedff47f240a third_party/protobuf (v3.7.0-rc.2-247-g09745575) From fdd856312a7a4e987629de816eaabcfad17623da Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 18:23:17 -0700 Subject: [PATCH 424/676] Modify class name and other small changes --- src/core/lib/iomgr/executor/mpmcqueue.cc | 97 +++++++++---------- src/core/lib/iomgr/executor/mpmcqueue.h | 45 ++++----- test/core/iomgr/mpmcqueue_test.cc | 114 ++++++++--------------- 3 files changed, 107 insertions(+), 149 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 7dc7be87e79..6deba05a421 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -29,40 +29,48 @@ #include #include "src/core/lib/debug/stats.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/sync.h" namespace grpc_core { -DebugOnlyTraceFlag thread_pool_trace(false, "thread_pool_trace"); +DebugOnlyTraceFlag thread_pool(false, "thread_pool_trace"); -inline void* MPMCQueue::PopFront() { +inline void* InfLenFIFOQueue::PopFront() { void* result = queue_head_->content; Node* head_to_remove = queue_head_; queue_head_ = queue_head_->next; - count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED); - gpr_timespec wait_time = - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); - - gpr_free(head_to_remove); - - // Update Stats info - stats_.num_completed++; - stats_.total_queue_cycles = - gpr_time_add(stats_.total_queue_cycles, wait_time); - stats_.max_queue_cycles = gpr_time_max( - gpr_convert_clock_type(stats_.max_queue_cycles, GPR_TIMESPAN), wait_time); + count_.FetchSub(1, MemoryOrder::RELAXED); - if (count_.Load(MemoryOrder::RELAXED) == 0) { - stats_.busy_time_cycles = - gpr_time_add(stats_.busy_time_cycles, - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); - } + if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + gpr_timespec wait_time = + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); - if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { - PrintStats(); + // Updates Stats info + stats_.num_completed++; + stats_.total_queue_cycles = + gpr_time_add(stats_.total_queue_cycles, wait_time); + stats_.max_queue_cycles = gpr_time_max( + gpr_convert_clock_type(stats_.max_queue_cycles, GPR_TIMESPAN), + wait_time); + + if (count_.Load(MemoryOrder::RELAXED) == 0) { + stats_.busy_time_cycles = + gpr_time_add(stats_.busy_time_cycles, + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); + } + + gpr_log(GPR_INFO, + "[InfLenFIFOQueue Get] num_completed: %" PRIu64 + " total_queue_cycles: %" PRId32 " max_queue_cycles: %" PRId32 + " busy_time_cycles: %" PRId32, + stats_.num_completed, gpr_time_to_millis(stats_.total_queue_cycles), + gpr_time_to_millis(stats_.max_queue_cycles), + gpr_time_to_millis(stats_.busy_time_cycles)); } + Delete(head_to_remove); // Singal waiting thread if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) { wait_nonempty_.Signal(); @@ -71,37 +79,34 @@ inline void* MPMCQueue::PopFront() { return result; } -MPMCQueue::MPMCQueue() - : num_waiters_(0), queue_head_(nullptr), queue_tail_(nullptr) { - count_.Store(0, MemoryOrder::RELAXED); -} +InfLenFIFOQueue::InfLenFIFOQueue() + : num_waiters_(0), queue_head_(nullptr), queue_tail_(nullptr) {} -MPMCQueue::~MPMCQueue() { +InfLenFIFOQueue::~InfLenFIFOQueue() { GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); - MutexLock l(&mu_); GPR_ASSERT(num_waiters_ == 0); } -void MPMCQueue::Put(void* elem) { +void InfLenFIFOQueue::Put(void* elem) { MutexLock l(&mu_); - Node* new_node = static_cast(gpr_malloc(sizeof(Node))); - new_node->next = nullptr; - new_node->content = elem; - new_node->insert_time = gpr_now(GPR_CLOCK_PRECISE); + Node* new_node = New(elem); if (count_.Load(MemoryOrder::RELAXED) == 0) { - busy_time = gpr_now(GPR_CLOCK_PRECISE); + if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + busy_time = gpr_now(GPR_CLOCK_PRECISE); + } queue_head_ = queue_tail_ = new_node; } else { queue_tail_->next = new_node; queue_tail_ = queue_tail_->next; } - count_.Store(count_.Load(MemoryOrder::RELAXED) + 1, MemoryOrder::RELAXED); + count_.FetchAdd(1, MemoryOrder::RELAXED); - // Update Stats info - stats_.num_started++; - if (GRPC_TRACE_FLAG_ENABLED(thread_pool_trace)) { - PrintStats(); + // Updates Stats info + if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + stats_.num_started++; + gpr_log(GPR_INFO, "[InfLenFIFOQueue Put] num_started: %" PRIu64, + stats_.num_started); } if (num_waiters_ > 0) { @@ -109,7 +114,7 @@ void MPMCQueue::Put(void* elem) { } } -void* MPMCQueue::Get() { +void* InfLenFIFOQueue::Get() { MutexLock l(&mu_); if (count_.Load(MemoryOrder::RELAXED) == 0) { num_waiters_++; @@ -118,20 +123,8 @@ void* MPMCQueue::Get() { } while (count_.Load(MemoryOrder::RELAXED) == 0); num_waiters_--; } - GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); + GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); return PopFront(); } -void MPMCQueue::PrintStats() { - gpr_log(GPR_INFO, "STATS INFO:"); - gpr_log(GPR_INFO, "num_started: %" PRIu64, stats_.num_started); - gpr_log(GPR_INFO, "num_completed: %" PRIu64, stats_.num_completed); - gpr_log(GPR_INFO, "total_queue_cycles: %" PRId32, - gpr_time_to_millis(stats_.total_queue_cycles)); - gpr_log(GPR_INFO, "max_queue_cycles: %" PRId32, - gpr_time_to_millis(stats_.max_queue_cycles)); - gpr_log(GPR_INFO, "busy_time_cycles: %" PRId32, - gpr_time_to_millis(stats_.busy_time_cycles)); -} - } // namespace grpc_core diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index aec8dd33c60..8b59b053bf9 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H -#define GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H +#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H #include @@ -31,46 +31,47 @@ namespace grpc_core { -extern DebugOnlyTraceFlag thread_pool_trace; +extern DebugOnlyTraceFlag thread_pool; -// Abstract base class of a MPMC queue interface +// Abstract base class of a Multiple-Producer-Multiple-Consumer(MPMC) queue +// interface class MPMCQueueInterface { public: virtual ~MPMCQueueInterface() {} - // Put elem into queue immediately at the end of queue. + // Puts elem into queue immediately at the end of queue. // This might cause to block on full queue depending on implementation. virtual void Put(void* elem) GRPC_ABSTRACT; - // Remove the oldest element from the queue and return it. + // Removes the oldest element from the queue and return it. // This might cause to block on empty queue depending on implementation. virtual void* Get() GRPC_ABSTRACT; - // Return number of elements in the queue currently + // Returns number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; GRPC_ABSTRACT_BASE_CLASS }; -class MPMCQueue : public MPMCQueueInterface { +class InfLenFIFOQueue : public MPMCQueueInterface { public: - // Create a new Multiple-Producer-Multiple-Consumer Queue. The queue created + // Creates a new MPMC Queue. The queue created // will have infinite length. - MPMCQueue(); + InfLenFIFOQueue(); - // Release all resources hold by the queue. The queue must be empty, and no + // Releases all resources hold by the queue. The queue must be empty, and no // one waiting on conditional variables. - ~MPMCQueue(); + ~InfLenFIFOQueue(); - // Put elem into queue immediately at the end of queue. Since the queue has + // Puts elem into queue immediately at the end of queue. Since the queue has // infinite length, this routine will never block and should never fail. void Put(void* elem); - // Remove the oldest element from the queue and return it. + // Removes the oldest element from the queue and returns it. // This routine will cause the thread to block if queue is currently empty. void* Get(); - // Return number of elements in queue currently. + // Returns number of elements in queue currently. // There might be concurrently add/remove on queue, so count might change // quickly. int count() const { return count_.Load(MemoryOrder::RELAXED); } @@ -78,11 +79,11 @@ class MPMCQueue : public MPMCQueueInterface { GRPC_ABSTRACT_BASE_CLASS private: + // For Internal Use Only. + // Removes the oldest element from the queue and returns it. This routine + // will NOT check whether queue is empty, and it will NOT acquire mutex. void* PopFront(); - // Print out Stats. Time measurement are printed in millisecond. - void PrintStats(); - struct Node { Node* next; // Linking void* content; // Points to actual element @@ -94,7 +95,9 @@ class MPMCQueue : public MPMCQueueInterface { } }; - struct Stats { // Stats of queue + // Stats of queue. This will only be collect when debug trace mode is on. + // All printed stats info will have time measurement in millisecond. + struct Stats { uint64_t num_started; // Number of elements have been added to queue uint64_t num_completed; // Number of elements have been removed from // the queue @@ -120,11 +123,11 @@ class MPMCQueue : public MPMCQueueInterface { Node* queue_head_; // Head of the queue, remove position Node* queue_tail_; // End of queue, insert position - Atomic count_; // Number of elements in queue + Atomic count_{0}; // Number of elements in queue Stats stats_; // Stats info gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core -#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H */ diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 12799d7895e..ebbf060961f 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -29,14 +29,6 @@ #define THREAD_SMALL_ITERATION 100 #define THREAD_LARGE_ITERATION 10000 -static void test_no_op(void) { - gpr_log(GPR_DEBUG, "test_no_op"); - grpc_core::MPMCQueue mpmcqueue; - gpr_log(GPR_DEBUG, "Checking count..."); - GPR_ASSERT(mpmcqueue.count() == 0); - gpr_log(GPR_DEBUG, "Done."); -} - // Testing items for queue struct WorkItem { int index; @@ -45,59 +37,44 @@ struct WorkItem { WorkItem(int i) : index(i) { done = false; } }; -static void test_small_queue(void) { - gpr_log(GPR_DEBUG, "test_small_queue"); - grpc_core::MPMCQueue small_queue; - for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { - small_queue.Put(static_cast(new WorkItem(i))); - } - GPR_ASSERT(small_queue.count() == THREAD_SMALL_ITERATION); - // Get items out in FIFO order - for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { - WorkItem* item = static_cast(small_queue.Get()); - GPR_ASSERT(i == item->index); - delete item; - } - gpr_log(GPR_DEBUG, "Done."); -} - -static void test_get_thd(void* args) { - grpc_core::MPMCQueue* mpmcqueue = static_cast(args); +static void ConsumerThread(void* args) { + grpc_core::InfLenFIFOQueue* queue = + static_cast(args); // count number of Get() called in this thread int count = 0; - int last_index = -1; + WorkItem* item; - while ((item = static_cast(mpmcqueue->Get())) != nullptr) { + while ((item = static_cast(queue->Get())) != nullptr) { count++; - GPR_ASSERT(item->index > last_index); - last_index = item->index; GPR_ASSERT(!item->done); - delete item; + item->done = true; } - gpr_log(GPR_DEBUG, "test_get_thd: %d times of Get() called.", count); + gpr_log(GPR_DEBUG, "ConsumerThread: %d times of Get() called.", count); } static void test_get_empty(void) { - gpr_log(GPR_DEBUG, "test_get_empty"); - grpc_core::MPMCQueue mpmcqueue; + gpr_log(GPR_INFO, "test_get_empty"); + grpc_core::InfLenFIFOQueue queue; + GPR_ASSERT(queue.count() == 0); const int num_threads = 10; grpc_core::Thread thds[num_threads]; // Fork threads. Threads should block at the beginning since queue is empty. for (int i = 0; i < num_threads; ++i) { - thds[i] = grpc_core::Thread("mpmcq_test_ge_thd", test_get_thd, &mpmcqueue); + thds[i] = + grpc_core::Thread("mpmcq_test_ge_thd", ConsumerThread, &queue); thds[i].Start(); } for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - mpmcqueue.Put(static_cast(new WorkItem(i))); + queue.Put(static_cast(new WorkItem(i))); } gpr_log(GPR_DEBUG, "Terminating threads..."); for (int i = 0; i < num_threads; ++i) { - mpmcqueue.Put(nullptr); + queue.Put(nullptr); } for (int i = 0; i < num_threads; ++i) { thds[i].Join(); @@ -105,9 +82,9 @@ static void test_get_empty(void) { gpr_log(GPR_DEBUG, "Done."); } -static void test_large_queue(void) { - gpr_log(GPR_DEBUG, "test_large_queue"); - grpc_core::MPMCQueue large_queue; +static void test_FIFO(void) { + gpr_log(GPR_INFO, "test_large_queue"); + grpc_core::InfLenFIFOQueue large_queue; for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { large_queue.Put(static_cast(new WorkItem(i))); } @@ -120,18 +97,19 @@ static void test_large_queue(void) { } // Thread for put items into queue -class WorkThread { +class ProducerThread { public: - WorkThread(grpc_core::MPMCQueue* mpmcqueue, int start_index, int num_items) + ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, + int num_items) : start_index_(start_index), num_items_(num_items), - mpmcqueue_(mpmcqueue) { + queue_(queue) { items_ = nullptr; thd_ = grpc_core::Thread( "mpmcq_test_mt_put_thd", - [](void* th) { static_cast(th)->Run(); }, this); + [](void* th) { static_cast(th)->Run(); }, this); } - ~WorkThread() { + ~ProducerThread() { for (int i = 0; i < num_items_; ++i) { GPR_ASSERT(items_[i]->done); delete items_[i]; @@ -147,63 +125,49 @@ class WorkThread { items_ = new WorkItem*[num_items_]; for (int i = 0; i < num_items_; ++i) { items_[i] = new WorkItem(start_index_ + i); - mpmcqueue_->Put(items_[i]); + queue_->Put(items_[i]); } } int start_index_; int num_items_; - grpc_core::MPMCQueue* mpmcqueue_; + grpc_core::InfLenFIFOQueue* queue_; grpc_core::Thread thd_; WorkItem** items_; }; -static void test_many_get_thd(void* args) { - grpc_core::MPMCQueue* mpmcqueue = static_cast(args); - - // count number of Get() called in this thread - int count = 0; - WorkItem* item; - while ((item = static_cast(mpmcqueue->Get())) != nullptr) { - count++; - GPR_ASSERT(!item->done); - item->done = true; - } - - gpr_log(GPR_DEBUG, "test_many_get_thd: %d times of Get() called.", count); -} static void test_many_thread(void) { - gpr_log(GPR_DEBUG, "test_many_thread"); + gpr_log(GPR_INFO, "test_many_thread"); const int num_work_thd = 10; const int num_get_thd = 20; - grpc_core::MPMCQueue mpmcqueue; - WorkThread** work_thds = new WorkThread*[num_work_thd]; + grpc_core::InfLenFIFOQueue queue; + ProducerThread** work_thds = new ProducerThread*[num_work_thd]; grpc_core::Thread get_thds[num_get_thd]; - gpr_log(GPR_DEBUG, "Fork WorkThread..."); + gpr_log(GPR_DEBUG, "Fork ProducerThread..."); for (int i = 0; i < num_work_thd; ++i) { - work_thds[i] = new WorkThread(&mpmcqueue, i * THREAD_LARGE_ITERATION, + work_thds[i] = new ProducerThread(&queue, i * THREAD_LARGE_ITERATION, THREAD_LARGE_ITERATION); work_thds[i]->Start(); } - gpr_log(GPR_DEBUG, "WorkThread Started."); - gpr_log(GPR_DEBUG, "For Getter Thread..."); + gpr_log(GPR_DEBUG, "ProducerThread Started."); + gpr_log(GPR_DEBUG, "Fork Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", test_many_get_thd, - &mpmcqueue); + get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", ConsumerThread, + &queue); get_thds[i].Start(); } gpr_log(GPR_DEBUG, "Getter Thread Started."); - gpr_log(GPR_DEBUG, "Waiting WorkThread to finish..."); + gpr_log(GPR_DEBUG, "Waiting ProducerThread to finish..."); for (int i = 0; i < num_work_thd; ++i) { work_thds[i]->Join(); } - gpr_log(GPR_DEBUG, "All WorkThread Terminated."); + gpr_log(GPR_DEBUG, "All ProducerThread Terminated."); gpr_log(GPR_DEBUG, "Terminating Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - mpmcqueue.Put(nullptr); + queue.Put(nullptr); } for (int i = 0; i < num_get_thd; ++i) { get_thds[i].Join(); @@ -221,10 +185,8 @@ int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); - test_no_op(); - test_small_queue(); test_get_empty(); - test_large_queue(); + test_FIFO(); test_many_thread(); grpc_shutdown(); return 0; From cb6924d48fe4f6187da66ae1ad3d12b26ce745b7 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 19:15:46 -0700 Subject: [PATCH 425/676] Fix header --- src/core/lib/iomgr/executor/mpmcqueue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 8b59b053bf9..2dee79737ca 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H -#define GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H +#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H #include @@ -130,4 +130,4 @@ class InfLenFIFOQueue : public MPMCQueueInterface { } // namespace grpc_core -#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_INFLENFIFOQUEUE_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_MPMCQUEUE_H */ From befd236fa3dcb3560b3fd15e8e57ca97c577f492 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 19:18:48 -0700 Subject: [PATCH 426/676] Remove extra --- src/core/lib/iomgr/executor/mpmcqueue.h | 2 - test/core/iomgr/mpmcqueue_test.cc | 83 ++++++++++++------------- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 2dee79737ca..a46e5ea28fd 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -49,8 +49,6 @@ class MPMCQueueInterface { // Returns number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS }; class InfLenFIFOQueue : public MPMCQueueInterface { diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index ebbf060961f..8f89b5c08bf 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -37,6 +37,47 @@ struct WorkItem { WorkItem(int i) : index(i) { done = false; } }; +// Thread for put items into queue +class ProducerThread { + public: + ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, + int num_items) + : start_index_(start_index), + num_items_(num_items), + queue_(queue) { + items_ = nullptr; + thd_ = grpc_core::Thread( + "mpmcq_test_mt_put_thd", + [](void* th) { static_cast(th)->Run(); }, this); + } + ~ProducerThread() { + for (int i = 0; i < num_items_; ++i) { + GPR_ASSERT(items_[i]->done); + delete items_[i]; + } + delete[] items_; + } + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + private: + void Run() { + items_ = new WorkItem*[num_items_]; + for (int i = 0; i < num_items_; ++i) { + items_[i] = new WorkItem(start_index_ + i); + queue_->Put(items_[i]); + } + } + + int start_index_; + int num_items_; + grpc_core::InfLenFIFOQueue* queue_; + grpc_core::Thread thd_; + WorkItem** items_; +}; + + static void ConsumerThread(void* args) { grpc_core::InfLenFIFOQueue* queue = static_cast(args); @@ -96,48 +137,6 @@ static void test_FIFO(void) { } } -// Thread for put items into queue -class ProducerThread { - public: - ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, - int num_items) - : start_index_(start_index), - num_items_(num_items), - queue_(queue) { - items_ = nullptr; - thd_ = grpc_core::Thread( - "mpmcq_test_mt_put_thd", - [](void* th) { static_cast(th)->Run(); }, this); - } - ~ProducerThread() { - for (int i = 0; i < num_items_; ++i) { - GPR_ASSERT(items_[i]->done); - delete items_[i]; - } - delete[] items_; - } - - void Start() { thd_.Start(); } - void Join() { thd_.Join(); } - - private: - void Run() { - items_ = new WorkItem*[num_items_]; - for (int i = 0; i < num_items_; ++i) { - items_[i] = new WorkItem(start_index_ + i); - queue_->Put(items_[i]); - } - } - - int start_index_; - int num_items_; - grpc_core::InfLenFIFOQueue* queue_; - grpc_core::Thread thd_; - WorkItem** items_; -}; - - - static void test_many_thread(void) { gpr_log(GPR_INFO, "test_many_thread"); const int num_work_thd = 10; From 87bd0a080aa5bc60f343d559fbb6051bea0e89a7 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 20 Jun 2019 19:21:59 -0700 Subject: [PATCH 427/676] Fix pos of base macro --- src/core/lib/iomgr/executor/mpmcqueue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index a46e5ea28fd..ae9a3b2826f 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -49,6 +49,8 @@ class MPMCQueueInterface { // Returns number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS }; class InfLenFIFOQueue : public MPMCQueueInterface { @@ -74,8 +76,6 @@ class InfLenFIFOQueue : public MPMCQueueInterface { // quickly. int count() const { return count_.Load(MemoryOrder::RELAXED); } - GRPC_ABSTRACT_BASE_CLASS - private: // For Internal Use Only. // Removes the oldest element from the queue and returns it. This routine From ef0f9bf7ec0ffec47554fd1eb9790835c2183728 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 20 Jun 2019 23:19:34 -0400 Subject: [PATCH 428/676] Introduce string_view and use it for gpr_split_host_port. --- BUILD | 8 +- BUILD.gn | 8 +- CMakeLists.txt | 44 ++++- Makefile | 54 +++++- build.yaml | 20 ++- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 6 +- gRPC-Core.podspec | 8 +- grpc.gemspec | 5 +- grpc.gyp | 2 +- package.xml | 5 +- .../ext/filters/client_channel/http_proxy.cc | 19 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 1 - .../client_channel/lb_policy/xds/xds.cc | 1 - .../filters/client_channel/parse_address.cc | 55 +++--- .../resolver/dns/c_ares/dns_resolver_ares.cc | 1 - .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 95 +++++----- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 1 - .../dns/c_ares/grpc_ares_wrapper_windows.cc | 1 - .../resolver/dns/native/dns_resolver.cc | 1 - .../resolver/fake/fake_resolver.cc | 1 - .../resolver/sockaddr/sockaddr_resolver.cc | 1 - .../transport/chttp2/server/chttp2_server.cc | 1 - .../transport/chttp2/transport/frame_data.cc | 8 +- .../cronet/transport/cronet_transport.cc | 1 - src/core/lib/channel/channelz.cc | 15 +- src/core/lib/gpr/host_port.cc | 98 ----------- src/core/lib/gpr/string.cc | 9 +- src/core/lib/gpr/string.h | 1 + src/core/lib/gprpp/host_port.cc | 97 +++++++++++ src/core/lib/{gpr => gprpp}/host_port.h | 38 ++-- src/core/lib/gprpp/string_view.h | 143 +++++++++++++++ .../lib/http/httpcli_security_connector.cc | 4 +- src/core/lib/iomgr/resolve_address_custom.cc | 35 ++-- src/core/lib/iomgr/resolve_address_posix.cc | 18 +- src/core/lib/iomgr/resolve_address_windows.cc | 14 +- src/core/lib/iomgr/sockaddr_utils.cc | 8 +- .../lib/iomgr/socket_utils_common_posix.cc | 1 - src/core/lib/iomgr/tcp_client_cfstream.cc | 13 +- .../alts/alts_security_connector.cc | 5 +- .../fake/fake_security_connector.cc | 46 +++-- .../local/local_security_connector.cc | 5 +- .../security_connector/security_connector.cc | 2 +- .../security_connector/security_connector.h | 2 +- .../ssl/ssl_security_connector.cc | 38 ++-- .../security/security_connector/ssl_utils.cc | 57 +++--- .../security/security_connector/ssl_utils.h | 19 +- .../tls/spiffe_security_connector.cc | 36 ++-- .../tls/spiffe_security_connector.h | 7 +- .../security/transport/client_auth_filter.cc | 3 +- .../alts/handshaker/alts_tsi_handshaker.cc | 1 - src/core/tsi/ssl_transport_security.cc | 78 ++++----- src/core/tsi/ssl_transport_security.h | 3 +- .../CronetTests/CoreCronetEnd2EndTests.mm | 16 +- .../tests/CronetTests/CronetUnitTests.mm | 14 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- test/core/bad_ssl/bad_ssl_test.cc | 8 +- .../parse_address_with_named_scope_id_test.cc | 17 +- test/core/end2end/bad_server_response_test.cc | 11 +- test/core/end2end/connection_refused_test.cc | 12 +- test/core/end2end/dualstack_socket_test.cc | 25 ++- test/core/end2end/fixtures/h2_census.cc | 22 ++- test/core/end2end/fixtures/h2_compress.cc | 33 ++-- test/core/end2end/fixtures/h2_fakesec.cc | 23 ++- test/core/end2end/fixtures/h2_full+pipe.cc | 21 ++- test/core/end2end/fixtures/h2_full+trace.cc | 21 ++- .../end2end/fixtures/h2_full+workarounds.cc | 24 ++- test/core/end2end/fixtures/h2_full.cc | 21 ++- test/core/end2end/fixtures/h2_http_proxy.cc | 27 ++- test/core/end2end/fixtures/h2_local_ipv4.cc | 4 +- test/core/end2end/fixtures/h2_local_ipv6.cc | 4 +- test/core/end2end/fixtures/h2_local_uds.cc | 8 +- test/core/end2end/fixtures/h2_oauth2.cc | 25 ++- test/core/end2end/fixtures/h2_proxy.cc | 1 - test/core/end2end/fixtures/h2_spiffe.cc | 25 +-- test/core/end2end/fixtures/h2_ssl.cc | 22 ++- .../end2end/fixtures/h2_ssl_cred_reload.cc | 24 ++- test/core/end2end/fixtures/h2_ssl_proxy.cc | 1 - test/core/end2end/fixtures/h2_uds.cc | 1 - .../end2end/fixtures/http_proxy_fixture.cc | 14 +- test/core/end2end/fixtures/inproc.cc | 1 - test/core/end2end/fixtures/local_util.cc | 15 +- test/core/end2end/fixtures/local_util.h | 6 +- test/core/end2end/fixtures/proxy.cc | 29 ++-- test/core/end2end/h2_ssl_cert_test.cc | 22 ++- .../core/end2end/h2_ssl_session_reuse_test.cc | 15 +- .../end2end/invalid_call_argument_test.cc | 15 +- test/core/fling/fling_stream_test.cc | 11 +- test/core/fling/fling_test.cc | 12 +- test/core/fling/server.cc | 12 +- test/core/gpr/BUILD | 10 -- test/core/gprpp/BUILD | 23 +++ test/core/{gpr => gprpp}/host_port_test.cc | 11 +- test/core/gprpp/string_view_test.cc | 163 ++++++++++++++++++ test/core/memory_usage/memory_usage_test.cc | 11 +- test/core/memory_usage/server.cc | 12 +- ...num_external_connectivity_watchers_test.cc | 21 +-- .../surface/sequential_connectivity_test.cc | 11 +- test/core/surface/server_chttp2_test.cc | 12 +- test/core/surface/server_test.cc | 14 +- test/core/util/reconnect_server.cc | 1 - test/core/util/test_tcp_server.cc | 1 - test/cpp/interop/interop_test.cc | 1 - test/cpp/naming/address_sorting_test.cc | 18 +- test/cpp/naming/cancel_ares_query_test.cc | 1 - test/cpp/naming/resolver_component_test.cc | 16 +- test/cpp/qps/client_sync.cc | 1 - test/cpp/qps/driver.cc | 22 +-- test/cpp/qps/qps_worker.cc | 9 +- test/cpp/qps/server_async.cc | 9 +- test/cpp/qps/server_callback.cc | 9 +- test/cpp/qps/server_sync.cc | 9 +- tools/doxygen/Doxyfile.c++.internal | 3 +- tools/doxygen/Doxyfile.core.internal | 5 +- .../generated/sources_and_headers.json | 28 ++- tools/run_tests/generated/tests.json | 24 +++ 117 files changed, 1277 insertions(+), 879 deletions(-) delete mode 100644 src/core/lib/gpr/host_port.cc create mode 100644 src/core/lib/gprpp/host_port.cc rename src/core/lib/{gpr => gprpp}/host_port.h (51%) create mode 100644 src/core/lib/gprpp/string_view.h rename test/core/{gpr => gprpp}/host_port_test.cc (86%) create mode 100644 test/core/gprpp/string_view_test.cc diff --git a/BUILD b/BUILD index 8fd52808400..821c3824948 100644 --- a/BUILD +++ b/BUILD @@ -558,7 +558,6 @@ grpc_cc_library( "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -585,6 +584,7 @@ grpc_cc_library( "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -594,7 +594,6 @@ grpc_cc_library( "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -611,14 +610,16 @@ grpc_cc_library( "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", @@ -627,6 +628,7 @@ grpc_cc_library( public_hdrs = GPR_PUBLIC_HDRS, deps = [ "gpr_codegen", + "grpc_codegen", ], ) diff --git a/BUILD.gn b/BUILD.gn index e5396f51426..9ae5b1ed22b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -141,8 +141,6 @@ config("grpc_config") { "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -189,6 +187,8 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.cc", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -480,6 +480,7 @@ config("grpc_config") { "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.cc", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.cc", @@ -1171,7 +1172,6 @@ config("grpc_config") { "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -1193,6 +1193,7 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/inlined_vector.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", @@ -1202,6 +1203,7 @@ config("grpc_config") { "src/core/lib/gprpp/pair.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/http/format_request.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 77a50d5ba46..0d33bca0a90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -713,6 +713,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx streaming_throughput_test) endif() add_dependencies(buildtests_cxx stress_test) +add_dependencies(buildtests_cxx string_view_test) add_dependencies(buildtests_cxx thread_manager_test) add_dependencies(buildtests_cxx thread_stress_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -860,7 +861,6 @@ add_library(gpr src/core/lib/gpr/env_linux.cc src/core/lib/gpr/env_posix.cc src/core/lib/gpr/env_windows.cc - src/core/lib/gpr/host_port.cc src/core/lib/gpr/log.cc src/core/lib/gpr/log_android.cc src/core/lib/gpr/log_linux.cc @@ -887,6 +887,7 @@ add_library(gpr src/core/lib/gprpp/arena.cc src/core/lib/gprpp/fork.cc src/core/lib/gprpp/global_config_env.cc + src/core/lib/gprpp/host_port.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -7505,7 +7506,7 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(gpr_host_port_test - test/core/gpr/host_port_test.cc + test/core/gprpp/host_port_test.cc ) @@ -16638,6 +16639,45 @@ target_link_libraries(stress_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(string_view_test + test/core/gprpp/string_view_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(string_view_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(string_view_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 0251d0f4f8e..02c57243cac 100644 --- a/Makefile +++ b/Makefile @@ -1278,6 +1278,7 @@ status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test status_util_test: $(BINDIR)/$(CONFIG)/status_util_test streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test +string_view_test: $(BINDIR)/$(CONFIG)/string_view_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test time_change_test: $(BINDIR)/$(CONFIG)/time_change_test @@ -1743,6 +1744,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ + $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -1905,6 +1907,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ + $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -2430,6 +2433,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 ) $(E) "[RUN] Testing streaming_throughput_test" $(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 ) + $(E) "[RUN] Testing string_view_test" + $(Q) $(BINDIR)/$(CONFIG)/string_view_test || ( echo test string_view_test failed ; exit 1 ) $(E) "[RUN] Testing thread_manager_test" $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(E) "[RUN] Testing thread_stress_test" @@ -3374,7 +3379,6 @@ LIBGPR_SRC = \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ - src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -3401,6 +3405,7 @@ LIBGPR_SRC = \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ + src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -10213,7 +10218,7 @@ endif GPR_HOST_PORT_TEST_SRC = \ - test/core/gpr/host_port_test.cc \ + test/core/gprpp/host_port_test.cc \ GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -10233,7 +10238,7 @@ $(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(C endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -19661,6 +19666,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc +STRING_VIEW_TEST_SRC = \ + test/core/gprpp/string_view_test.cc \ + +STRING_VIEW_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRING_VIEW_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/string_view_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.5.0+. + +$(BINDIR)/$(CONFIG)/string_view_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/string_view_test: $(PROTOBUF_DEP) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/string_view_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/string_view_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_string_view_test: $(STRING_VIEW_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(STRING_VIEW_TEST_OBJS:.o=.dep) +endif +endif + + THREAD_MANAGER_TEST_SRC = \ test/cpp/thread_manager/thread_manager_test.cc \ diff --git a/build.yaml b/build.yaml index dad2146bd1c..41c32396a42 100644 --- a/build.yaml +++ b/build.yaml @@ -122,7 +122,6 @@ filegroups: - src/core/lib/gpr/env_linux.cc - src/core/lib/gpr/env_posix.cc - src/core/lib/gpr/env_windows.cc - - src/core/lib/gpr/host_port.cc - src/core/lib/gpr/log.cc - src/core/lib/gpr/log_android.cc - src/core/lib/gpr/log_linux.cc @@ -149,6 +148,7 @@ filegroups: - src/core/lib/gprpp/arena.cc - src/core/lib/gprpp/fork.cc - src/core/lib/gprpp/global_config_env.cc + - src/core/lib/gprpp/host_port.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -178,7 +178,6 @@ filegroups: - src/core/lib/gpr/alloc.h - src/core/lib/gpr/arena.h - src/core/lib/gpr/env.h - - src/core/lib/gpr/host_port.h - src/core/lib/gpr/mpscq.h - src/core/lib/gpr/murmur_hash.h - src/core/lib/gpr/spinlock.h @@ -199,6 +198,7 @@ filegroups: - src/core/lib/gprpp/global_config_custom.h - src/core/lib/gprpp/global_config_env.h - src/core/lib/gprpp/global_config_generic.h + - src/core/lib/gprpp/host_port.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h @@ -444,6 +444,7 @@ filegroups: - src/core/lib/gprpp/orphanable.h - src/core/lib/gprpp/ref_counted.h - src/core/lib/gprpp/ref_counted_ptr.h + - src/core/lib/gprpp/string_view.h - src/core/lib/http/format_request.h - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h @@ -2625,7 +2626,7 @@ targets: build: test language: c src: - - test/core/gpr/host_port_test.cc + - test/core/gprpp/host_port_test.cc deps: - gpr - grpc_test_util_unsecure @@ -5760,6 +5761,19 @@ targets: - grpc - gpr - grpc++_test_config +- name: string_view_test + gtest: true + build: test + language: c++ + src: + - test/core/gprpp/string_view_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: thread_manager_test build: test language: c++ diff --git a/config.m4 b/config.m4 index bb30be56910..99d49d391b4 100644 --- a/config.m4 +++ b/config.m4 @@ -53,7 +53,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ - src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -80,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ + src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ diff --git a/config.w32 b/config.w32 index c9faa8d9ac8..f6c6b4fde10 100644 --- a/config.w32 +++ b/config.w32 @@ -28,7 +28,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gpr\\env_linux.cc " + "src\\core\\lib\\gpr\\env_posix.cc " + "src\\core\\lib\\gpr\\env_windows.cc " + - "src\\core\\lib\\gpr\\host_port.cc " + "src\\core\\lib\\gpr\\log.cc " + "src\\core\\lib\\gpr\\log_android.cc " + "src\\core\\lib\\gpr\\log_linux.cc " + @@ -55,6 +54,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gprpp\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + "src\\core\\lib\\gprpp\\global_config_env.cc " + + "src\\core\\lib\\gprpp\\host_port.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index f0a4418b20c..17b44738cc2 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -261,7 +261,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -282,6 +281,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -444,6 +444,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -591,7 +592,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -612,6 +612,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -648,6 +649,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2e34e8d7573..6255fdfd0ce 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -191,7 +191,6 @@ Pod::Spec.new do |s| ss.source_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -212,6 +211,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -228,7 +228,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -255,6 +254,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -414,6 +414,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -884,7 +885,6 @@ Pod::Spec.new do |s| ss.private_header_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -905,6 +905,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -1067,6 +1068,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/grpc.gemspec b/grpc.gemspec index 11469a3ec5c..a1051fd4685 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -85,7 +85,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/alloc.h ) s.files += %w( src/core/lib/gpr/arena.h ) s.files += %w( src/core/lib/gpr/env.h ) - s.files += %w( src/core/lib/gpr/host_port.h ) s.files += %w( src/core/lib/gpr/mpscq.h ) s.files += %w( src/core/lib/gpr/murmur_hash.h ) s.files += %w( src/core/lib/gpr/spinlock.h ) @@ -106,6 +105,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/global_config_custom.h ) s.files += %w( src/core/lib/gprpp/global_config_env.h ) s.files += %w( src/core/lib/gprpp/global_config_generic.h ) + s.files += %w( src/core/lib/gprpp/host_port.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) @@ -122,7 +122,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/env_linux.cc ) s.files += %w( src/core/lib/gpr/env_posix.cc ) s.files += %w( src/core/lib/gpr/env_windows.cc ) - s.files += %w( src/core/lib/gpr/host_port.cc ) s.files += %w( src/core/lib/gpr/log.cc ) s.files += %w( src/core/lib/gpr/log_android.cc ) s.files += %w( src/core/lib/gpr/log_linux.cc ) @@ -149,6 +148,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) s.files += %w( src/core/lib/gprpp/global_config_env.cc ) + s.files += %w( src/core/lib/gprpp/host_port.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) @@ -348,6 +348,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/orphanable.h ) s.files += %w( src/core/lib/gprpp/ref_counted.h ) s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h ) + s.files += %w( src/core/lib/gprpp/string_view.h ) s.files += %w( src/core/lib/http/format_request.h ) s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) diff --git a/grpc.gyp b/grpc.gyp index 6268bed7bb0..784279301d3 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -226,7 +226,6 @@ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -253,6 +252,7 @@ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/package.xml b/package.xml index 616e1ece20e..388e8d8620a 100644 --- a/package.xml +++ b/package.xml @@ -90,7 +90,6 @@ - @@ -111,6 +110,7 @@ + @@ -127,7 +127,6 @@ - @@ -154,6 +153,7 @@ + @@ -353,6 +353,7 @@ + diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc index 8951a2920c4..9e60a553ceb 100644 --- a/src/core/ext/filters/client_channel/http_proxy.cc +++ b/src/core/ext/filters/client_channel/http_proxy.cc @@ -31,8 +31,8 @@ #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/slice/b64.h" #include "src/core/lib/uri/uri_parser.h" @@ -126,17 +126,18 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, if (no_proxy_str != nullptr) { static const char* NO_PROXY_SEPARATOR = ","; bool use_proxy = true; - char* server_host; - char* server_port; - if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path, - &server_host, &server_port)) { + grpc_core::UniquePtr server_host; + grpc_core::UniquePtr server_port; + if (!grpc_core::SplitHostPort( + uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host, + &server_port)) { gpr_log(GPR_INFO, "unable to split host and port, not checking no_proxy list for " "host '%s'", server_uri); gpr_free(no_proxy_str); } else { - size_t uri_len = strlen(server_host); + size_t uri_len = strlen(server_host.get()); char** no_proxy_hosts; size_t num_no_proxy_hosts; gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts, @@ -145,8 +146,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, char* no_proxy_entry = no_proxy_hosts[i]; size_t no_proxy_len = strlen(no_proxy_entry); if (no_proxy_len <= uri_len && - gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) == - 0) { + gpr_stricmp(no_proxy_entry, + &(server_host.get()[uri_len - no_proxy_len])) == 0) { gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'", server_uri); use_proxy = false; @@ -157,8 +158,6 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, gpr_free(no_proxy_hosts[i]); } gpr_free(no_proxy_hosts); - gpr_free(server_host); - gpr_free(server_port); gpr_free(no_proxy_str); if (!use_proxy) goto no_use_proxy; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 2f3516066da..71e8e248770 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -84,7 +84,6 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e5c27fe67a4..ca9ea9e31cc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -84,7 +84,6 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/map.h" diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index c5e1ed811bc..fbfbb4445f3 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -33,8 +33,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #ifdef GRPC_POSIX_SOCKET #include @@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - char* host; - char* port; - if (!gpr_split_host_port(hostport, &host, &port)) { + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + if (!grpc_core::SplitHostPort(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -86,8 +86,10 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, addr->len = static_cast(sizeof(grpc_sockaddr_in)); grpc_sockaddr_in* in = reinterpret_cast(addr->addr); in->sin_family = GRPC_AF_INET; - if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host); + if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) { + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get()); + } goto done; } // Parse port. @@ -96,15 +98,14 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port); + if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get()); goto done; } in->sin_port = grpc_htons(static_cast(port_num)); success = true; done: - gpr_free(host); - gpr_free(port); return success; } @@ -124,9 +125,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - char* host; - char* port; - if (!gpr_split_host_port(hostport, &host, &port)) { + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + if (!grpc_core::SplitHostPort(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -138,11 +139,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, grpc_sockaddr_in6* in6 = reinterpret_cast(addr->addr); in6->sin6_family = GRPC_AF_INET6; // Handle the RFC6874 syntax for IPv6 zone identifiers. - char* host_end = static_cast(gpr_memrchr(host, '%', strlen(host))); + char* host_end = + static_cast(gpr_memrchr(host.get(), '%', strlen(host.get()))); if (host_end != nullptr) { - GPR_ASSERT(host_end >= host); + GPR_ASSERT(host_end >= host.get()); char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1]; - size_t host_without_scope_len = static_cast(host_end - host); + size_t host_without_scope_len = static_cast(host_end - host.get()); uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { if (log_errors) { @@ -154,7 +156,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - strncpy(host_without_scope, host, host_without_scope_len); + strncpy(host_without_scope, host.get(), host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { @@ -163,9 +165,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - if (gpr_parse_bytes_to_uint32(host_end + 1, - strlen(host) - host_without_scope_len - 1, - &sin6_scope_id) == 0) { + if (gpr_parse_bytes_to_uint32( + host_end + 1, strlen(host.get()) - host_without_scope_len - 1, + &sin6_scope_id) == 0) { if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { gpr_log(GPR_ERROR, "Invalid interface name: '%s'. " @@ -177,8 +179,10 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; } else { - if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); + if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) { + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get()); + } goto done; } } @@ -188,15 +192,14 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); + if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get()); goto done; } in6->sin6_port = grpc_htons(static_cast(port_num)); success = true; done: - gpr_free(host); - gpr_free(port); return success; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 32a339af359..ff15704d692 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -38,7 +38,6 @@ #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index ad0f1460121..0c1a8ba828f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -35,8 +35,8 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" @@ -355,9 +355,9 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; /* parse name, splitting it into host and port parts */ - char* host; - char* port; - gpr_split_host_port(name, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(name, &host, &port); if (host == nullptr) { error = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -370,7 +370,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto error_cleanup; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, query_timeout_ms, combiner, r); @@ -414,20 +414,22 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( } r->pending_queries = 1; if (grpc_ares_query_ipv6()) { - hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), - false /* is_balancer */); + hr = create_hostbyname_request_locked(r, host.get(), + grpc_strhtons(port.get()), + /*is_balancer=*/false); ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked, hr); } - hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), - false /* is_balancer */); + hr = + create_hostbyname_request_locked(r, host.get(), grpc_strhtons(port.get()), + /*is_balancer=*/false); ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked, hr); if (check_grpclb) { /* Query the SRV record */ grpc_ares_request_ref_locked(r); char* service_name; - gpr_asprintf(&service_name, "_grpclb._tcp.%s", host); + gpr_asprintf(&service_name, "_grpclb._tcp.%s", host.get()); ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_locked, r); gpr_free(service_name); @@ -435,28 +437,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( if (r->service_config_json_out != nullptr) { grpc_ares_request_ref_locked(r); char* config_name; - gpr_asprintf(&config_name, "_grpc_config.%s", host); + gpr_asprintf(&config_name, "_grpc_config.%s", host.get()); ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked, r); gpr_free(config_name); } grpc_ares_ev_driver_start_locked(r->ev_driver); grpc_ares_request_unref_locked(r); - gpr_free(host); - gpr_free(port); return; error_cleanup: GRPC_CLOSURE_SCHED(r->on_done, error); - gpr_free(host); - gpr_free(port); } static bool inner_resolve_as_ip_literal_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port, char** hostport) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* port, + grpc_core::UniquePtr* hostport) { + grpc_core::SplitHostPort(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s to host:port while attempting to resolve as ip " @@ -472,12 +471,14 @@ static bool inner_resolve_as_ip_literal_locked( name); return false; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } grpc_resolved_address addr; - GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port))); - if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || - grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { + GPR_ASSERT(grpc_core::JoinHostPort(hostport, host->get(), atoi(port->get()))); + if (grpc_parse_ipv4_hostport(hostport->get(), &addr, + false /* log errors */) || + grpc_parse_ipv6_hostport(hostport->get(), &addr, + false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); @@ -489,24 +490,22 @@ static bool inner_resolve_as_ip_literal_locked( static bool resolve_as_ip_literal_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - char* hostport = nullptr; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::UniquePtr hostport; bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs, &host, &port, &hostport); - gpr_free(host); - gpr_free(port); - gpr_free(hostport); return out; } -static bool target_matches_localhost_inner(const char* name, char** host, - char** port) { - if (!gpr_split_host_port(name, host, port)) { +static bool target_matches_localhost_inner(const char* name, + grpc_core::UniquePtr* host, + grpc_core::UniquePtr* port) { + if (!grpc_core::SplitHostPort(name, host, port)) { gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); return false; } - if (gpr_stricmp(*host, "localhost") == 0) { + if (gpr_stricmp(host->get(), "localhost") == 0) { return true; } else { return false; @@ -514,20 +513,17 @@ static bool target_matches_localhost_inner(const char* name, char** host, } static bool target_matches_localhost(const char* name) { - char* host = nullptr; - char* port = nullptr; - bool out = target_matches_localhost_inner(name, &host, &port); - gpr_free(host); - gpr_free(port); - return out; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + return target_matches_localhost_inner(name, &host, &port); } #ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY static bool inner_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* port) { + grpc_core::SplitHostPort(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s into host:port during manual localhost " @@ -543,12 +539,12 @@ static bool inner_maybe_resolve_localhost_manually_locked( name); return false; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } - if (gpr_stricmp(*host, "localhost") == 0) { + if (gpr_stricmp(host->get(), "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); + uint16_t numeric_port = grpc_strhtons(port->get()); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); @@ -576,13 +572,10 @@ static bool inner_maybe_resolve_localhost_manually_locked( static bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + return inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); } #else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ static bool grpc_ares_maybe_resolve_localhost_manually_locked( diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index f85feb674dd..d9e3293deb6 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" bool grpc_ares_query_ipv6() { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 06cd5722ce3..1749cf77201 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 5ab75d02793..b8434a1cae4 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 7f613ee21bc..ff728a3dc43 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -32,7 +32,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 1465b0c644e..517b9297af4 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -30,7 +30,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 8285ee76445..dc60ec2487b 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -37,7 +37,6 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resource_quota.h" diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 74c305b820f..c50d7e48d41 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - p->error = - grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_dump_slice_to_slice( - *slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); + p->error = grpc_error_set_str( + p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_moved_string(grpc_core::UniquePtr( + grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)))); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 3ddda268cfb..a5f6571c510 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -30,7 +30,6 @@ #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/cronet/transport/cronet_transport.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/endpoint.h" diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 4b130372e46..184ba17889d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -30,9 +30,9 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -406,14 +406,15 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, (strcmp(uri->scheme, "ipv6") == 0))) { const char* host_port = uri->path; if (*host_port == '/') ++host_port; - char* host = nullptr; - char* port = nullptr; - GPR_ASSERT(gpr_split_host_port(host_port, &host, &port)); + UniquePtr host; + UniquePtr port; + GPR_ASSERT(SplitHostPort(host_port, &host, &port)); int port_num = -1; if (port != nullptr) { - port_num = atoi(port); + port_num = atoi(port.get()); } - char* b64_host = grpc_base64_encode(host, strlen(host), false, false); + char* b64_host = + grpc_base64_encode(host.get(), strlen(host.get()), false, false); json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr, GRPC_JSON_OBJECT, false); json = json_iterator; @@ -422,8 +423,6 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, "port", port_num); json_iterator = grpc_json_create_child(json_iterator, json, "ip_address", b64_host, GRPC_JSON_STRING, true); - gpr_free(host); - gpr_free(port); } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) { json_iterator = grpc_json_create_child(json_iterator, json, "uds_address", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/core/lib/gpr/host_port.cc b/src/core/lib/gpr/host_port.cc deleted file mode 100644 index a34e01cb516..00000000000 --- a/src/core/lib/gpr/host_port.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/gpr/host_port.h" - -#include - -#include -#include -#include - -#include "src/core/lib/gpr/string.h" - -int gpr_join_host_port(char** out, const char* host, int port) { - if (host[0] != '[' && strchr(host, ':') != nullptr) { - /* IPv6 literals must be enclosed in brackets. */ - return gpr_asprintf(out, "[%s]:%d", host, port); - } else { - /* Ordinary non-bracketed host:port. */ - return gpr_asprintf(out, "%s:%d", host, port); - } -} - -int gpr_split_host_port(const char* name, char** host, char** port) { - const char* host_start; - size_t host_len; - const char* port_start; - - *host = nullptr; - *port = nullptr; - - if (name[0] == '[') { - /* Parse a bracketed host, typically an IPv6 literal. */ - const char* rbracket = strchr(name, ']'); - if (rbracket == nullptr) { - /* Unmatched [ */ - return 0; - } - if (rbracket[1] == '\0') { - /* ] */ - port_start = nullptr; - } else if (rbracket[1] == ':') { - /* ]: */ - port_start = rbracket + 2; - } else { - /* ] */ - return 0; - } - host_start = name + 1; - host_len = static_cast(rbracket - host_start); - if (memchr(host_start, ':', host_len) == nullptr) { - /* Require all bracketed hosts to contain a colon, because a hostname or - IPv4 address should never use brackets. */ - return 0; - } - } else { - const char* colon = strchr(name, ':'); - if (colon != nullptr && strchr(colon + 1, ':') == nullptr) { - /* Exactly 1 colon. Split into host:port. */ - host_start = name; - host_len = static_cast(colon - name); - port_start = colon + 1; - } else { - /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ - host_start = name; - host_len = strlen(name); - port_start = nullptr; - } - } - - /* Allocate return values. */ - *host = static_cast(gpr_malloc(host_len + 1)); - memcpy(*host, host_start, host_len); - (*host)[host_len] = '\0'; - - if (port_start != nullptr) { - *port = gpr_strdup(port_start); - } - - return 1; -} diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index a39f56ef926..14436ec1bf9 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -289,17 +289,22 @@ 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 gpr_strincmp(const char* a, const char* b, size_t n) { int ca, cb; do { ca = tolower(*a); cb = tolower(*b); ++a; ++b; - } while (ca == cb && ca && cb); + --n; + } while (ca == cb && ca != 0 && cb != 0 && n != 0); return ca - cb; } +int gpr_stricmp(const char* a, const char* b) { + return gpr_strincmp(a, b, SIZE_MAX); +} + static void add_string_to_split(const char* beg, const char* end, char*** strs, size_t* nstrs, size_t* capstrs) { char* out = diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index bf59db7abfe..fcccf5e6764 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -115,6 +115,7 @@ 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); +int gpr_strincmp(const char* a, const char* b, size_t n); void* gpr_memrchr(const void* s, int c, size_t n); diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc new file mode 100644 index 00000000000..f3f8a73602a --- /dev/null +++ b/src/core/lib/gprpp/host_port.cc @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/host_port.h" + +#include + +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/string_view.h" + +namespace grpc_core { +int JoinHostPort(UniquePtr* out, const char* host, int port) { + char* tmp; + int ret; + if (host[0] != '[' && strchr(host, ':') != nullptr) { + /* IPv6 literals must be enclosed in brackets. */ + ret = gpr_asprintf(&tmp, "[%s]:%d", host, port); + } else { + /* Ordinary non-bracketed host:port. */ + ret = gpr_asprintf(&tmp, "%s:%d", host, port); + } + out->reset(tmp); + return ret; +} + +bool SplitHostPort(StringView name, StringView* host, StringView* port) { + if (name[0] == '[') { + /* Parse a bracketed host, typically an IPv6 literal. */ + const size_t rbracket = name.find(']', 1); + if (rbracket == grpc_core::StringView::npos) { + /* Unmatched [ */ + return false; + } + if (rbracket == name.size() - 1) { + /* ] */ + port->clear(); + } else if (name[rbracket + 1] == ':') { + /* ]: */ + *port = name.substr(rbracket + 2, name.size() - rbracket - 2); + } else { + /* ] */ + return false; + } + *host = name.substr(1, rbracket - 1); + if (host->find(':') == grpc_core::StringView::npos) { + /* Require all bracketed hosts to contain a colon, because a hostname or + IPv4 address should never use brackets. */ + host->clear(); + return false; + } + } else { + size_t colon = name.find(':'); + if (colon != grpc_core::StringView::npos && + name.find(':', colon + 1) == grpc_core::StringView::npos) { + /* Exactly 1 colon. Split into host:port. */ + *host = name.substr(0, colon); + *port = name.substr(colon + 1, name.size() - colon - 1); + } else { + /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ + *host = name; + port->clear(); + } + } + return true; +} + +bool SplitHostPort(StringView name, UniquePtr* host, + UniquePtr* port) { + StringView host_view; + StringView port_view; + const bool ret = SplitHostPort(name, &host_view, &port_view); + host->reset(host_view.empty() ? nullptr : host_view.dup().release()); + port->reset(port_view.empty() ? nullptr : port_view.dup().release()); + return ret; +} +} // namespace grpc_core diff --git a/src/core/lib/gpr/host_port.h b/src/core/lib/gprpp/host_port.h similarity index 51% rename from src/core/lib/gpr/host_port.h rename to src/core/lib/gprpp/host_port.h index 0bf0960f824..16f1c807580 100644 --- a/src/core/lib/gpr/host_port.h +++ b/src/core/lib/gprpp/host_port.h @@ -16,28 +16,44 @@ * */ -#ifndef GRPC_CORE_LIB_GPR_HOST_PORT_H -#define GRPC_CORE_LIB_GPR_HOST_PORT_H +#ifndef GRPC_CORE_LIB_GPRPP_HOST_PORT_H +#define GRPC_CORE_LIB_GPRPP_HOST_PORT_H #include +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/string_view.h" + +namespace grpc_core { + /** Given a host and port, creates a newly-allocated string of the form "host:port" or "[ho:st]:port", depending on whether the host contains colons like an IPv6 literal. If the host is already bracketed, then additional brackets will not be added. Usage is similar to gpr_asprintf: returns the number of bytes written - (excluding the final '\0'), and *out points to a string which must later be - destroyed using gpr_free(). + (excluding the final '\0'), and *out points to a string. In the unlikely event of an error, returns -1 and sets *out to NULL. */ -int gpr_join_host_port(char** out, const char* host, int port); +int JoinHostPort(UniquePtr* out, const char* host, int port); /** Given a name in the form "host:port" or "[ho:st]:port", split into hostname - and port number, into newly allocated strings, which must later be - destroyed using gpr_free(). - Return 1 on success, 0 on failure. Guarantees *host and *port == NULL on - failure. */ -int gpr_split_host_port(const char* name, char** host, char** port); + and port number. + + There are two variants of this method: + 1) StringView ouptut: port and host are returned as views on name. + 2) char* output: port and host are copied into newly allocated strings. + + Prefer variant (1) over (2), because no allocation or copy is performed in + variant (1). Use (2) only when interacting with C API that mandate + null-terminated strings. + + Return true on success, false on failure. Guarantees *host and *port are + cleared on failure. */ +bool SplitHostPort(StringView name, StringView* host, StringView* port); +bool SplitHostPort(StringView name, UniquePtr* host, + UniquePtr* port); + +} // namespace grpc_core -#endif /* GRPC_CORE_LIB_GPR_HOST_PORT_H */ +#endif /* GRPC_CORE_LIB_GPRPP_HOST_PORT_H */ diff --git a/src/core/lib/gprpp/string_view.h b/src/core/lib/gprpp/string_view.h new file mode 100644 index 00000000000..05a81066d48 --- /dev/null +++ b/src/core/lib/gprpp/string_view.h @@ -0,0 +1,143 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef GRPC_CORE_LIB_GPRPP_STRING_VIEW_H +#define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { + +// Provides a light-weight view over a char array or a slice, similar but not +// identical to absl::string_view. +// +// Any method that has the same name as absl::string_view MUST HAVE identical +// semantics to what absl::string_view provides. +// +// Methods that are not part of absl::string_view API, must be clearly +// annotated. +// +// StringView does not own the buffers that back the view. Callers must ensure +// the buffer stays around while the StringView is accessible. +// +// Pass StringView by value in functions, since it is exactly two pointers in +// size. +// +// The interface used here is not identical to absl::string_view. Notably, we +// need to support slices while we cannot support std::string, and gpr string +// style functions such as strdup() and cmp(). Once we switch to +// absl::string_view this class will inherit from absl::string_view and add the +// gRPC-specific APIs. +class StringView final { + public: + static constexpr size_t npos = std::numeric_limits::max(); + + constexpr StringView(const char* ptr, size_t size) : ptr_(ptr), size_(size) {} + constexpr StringView(const char* ptr) + : StringView(ptr, ptr == nullptr ? 0 : strlen(ptr)) {} + // Not part of absl::string_view API. + StringView(const grpc_slice& slice) + : StringView(reinterpret_cast(GRPC_SLICE_START_PTR(slice)), + GRPC_SLICE_LENGTH(slice)) {} + constexpr StringView() : StringView(nullptr, 0) {} + + constexpr const char* data() const { return ptr_; } + constexpr size_t size() const { return size_; } + constexpr bool empty() const { return size_ == 0; } + + StringView substr(size_t start, size_t size = npos) { + GPR_DEBUG_ASSERT(start + size <= size_); + return StringView(ptr_ + start, std::min(size, size_ - start)); + } + + constexpr const char& operator[](size_t i) const { return ptr_[i]; } + + const char& front() const { return ptr_[0]; } + const char& back() const { return ptr_[size_ - 1]; } + + void remove_prefix(size_t n) { + GPR_DEBUG_ASSERT(n <= size_); + ptr_ += n; + size_ -= n; + } + + void remove_suffix(size_t n) { + GPR_DEBUG_ASSERT(n <= size_); + size_ -= n; + } + + size_t find(char c, size_t pos = 0) const { + if (empty() || pos >= size_) return npos; + const char* result = + static_cast(memchr(ptr_ + pos, c, size_ - pos)); + return result != nullptr ? result - ptr_ : npos; + } + + void clear() { + ptr_ = nullptr; + size_ = 0; + } + + // Creates a dup of the string viewed by this class. + // Return value is null-terminated and never nullptr. + // + // Not part of absl::string_view API. + grpc_core::UniquePtr dup() const { + char* str = static_cast(gpr_malloc(size_ + 1)); + if (size_ > 0) memcpy(str, ptr_, size_); + str[size_] = '\0'; + return grpc_core::UniquePtr(str); + } + + // Not part of absl::string_view API. + int cmp(StringView other) const { + const size_t len = GPR_MIN(size(), other.size()); + const int ret = strncmp(data(), other.data(), len); + if (ret != 0) return ret; + if (size() == other.size()) return 0; + if (size() < other.size()) return -1; + return 1; + } + + private: + const char* ptr_; + size_t size_; +}; + +inline bool operator==(StringView lhs, StringView rhs) { + return lhs.size() == rhs.size() && + strncmp(lhs.data(), rhs.data(), lhs.size()) == 0; +} + +inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); } + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 762cbe41bcf..8196019f098 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -108,7 +109,8 @@ class grpc_httpcli_ssl_channel_security_connector final return strcmp(secure_peer_name_, other->secure_peer_name_); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { *error = GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/resolve_address_custom.cc b/src/core/lib/iomgr/resolve_address_custom.cc index 9cf7817f66e..64c33cdc0d4 100644 --- a/src/core/lib/iomgr/resolve_address_custom.cc +++ b/src/core/lib/iomgr/resolve_address_custom.cc @@ -24,9 +24,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address_custom.h" @@ -86,11 +86,12 @@ void grpc_custom_resolve_callback(grpc_custom_resolver* r, } static grpc_error* try_split_host_port(const char* name, - const char* default_port, char** host, - char** port) { + const char* default_port, + grpc_core::UniquePtr* host, + grpc_core::UniquePtr* port) { /* parse name, splitting it into host and port parts */ grpc_error* error; - gpr_split_host_port(name, host, port); + SplitHostPort(name, host, port); if (*host == nullptr) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -107,7 +108,7 @@ static grpc_error* try_split_host_port(const char* name, gpr_free(msg); return error; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } return GRPC_ERROR_NONE; } @@ -115,28 +116,26 @@ static grpc_error* try_split_host_port(const char* name, static grpc_error* blocking_resolve_address_impl( const char* name, const char* default_port, grpc_resolved_addresses** addresses) { - char* host; - char* port; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { - gpr_free(host); - gpr_free(port); return err; } /* Call getaddrinfo */ grpc_custom_resolver resolver; - resolver.host = host; - resolver.port = port; + resolver.host = host.get(); + resolver.port = port.get(); grpc_resolved_addresses* addrs; grpc_core::ExecCtx* curr = grpc_core::ExecCtx::Get(); grpc_core::ExecCtx::Set(nullptr); - err = resolve_address_vtable->resolve(host, port, &addrs); + err = resolve_address_vtable->resolve(host.get(), port.get(), &addrs); if (err != GRPC_ERROR_NONE) { if (retry_named_port_failure(&resolver, &addrs)) { GRPC_ERROR_UNREF(err); @@ -147,8 +146,6 @@ static grpc_error* blocking_resolve_address_impl( if (err == GRPC_ERROR_NONE) { *addresses = addrs; } - gpr_free(resolver.host); - gpr_free(resolver.port); return err; } @@ -157,22 +154,20 @@ static void resolve_address_impl(const char* name, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_custom_resolver* r = nullptr; - char* host = nullptr; - char* port = nullptr; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_done, err); - gpr_free(host); - gpr_free(port); return; } r = (grpc_custom_resolver*)gpr_malloc(sizeof(grpc_custom_resolver)); r->on_done = on_done; r->addresses = addrs; - r->host = host; - r->port = port; + r->host = host.release(); + r->port = port.release(); /* Call getaddrinfo */ resolve_address_vtable->resolve_async(r, r->host, r->port); diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index e6dd8f1ceab..e02dc19bb27 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -33,9 +33,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -48,8 +48,6 @@ static grpc_error* posix_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = nullptr, *resp; - char* host; - char* port; int s; size_t i; grpc_error* err; @@ -59,8 +57,10 @@ static grpc_error* posix_blocking_resolve_address( return grpc_resolve_unix_domain_address(name + 5, addresses); } + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); + grpc_core::SplitHostPort(name, &host, &port); if (host == nullptr) { err = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -74,7 +74,7 @@ static grpc_error* posix_blocking_resolve_address( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto done; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } /* Call getaddrinfo */ @@ -84,16 +84,16 @@ static grpc_error* posix_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); + s = getaddrinfo(host.get(), port.get(), &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { /* Retry if well-known service name is recognized */ const char* svc[][2] = {{"http", "80"}, {"https", "443"}}; for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { - if (strcmp(port, svc[i][0]) == 0) { + if (strcmp(port.get(), svc[i][0]) == 0) { GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, svc[i][1], &hints, &result); + s = getaddrinfo(host.get(), svc[i][1], &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; break; } @@ -133,8 +133,6 @@ static grpc_error* posix_blocking_resolve_address( err = GRPC_ERROR_NONE; done: - gpr_free(host); - gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 64351c38a8f..a06d5cefbcb 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -35,8 +35,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -57,14 +57,14 @@ static grpc_error* windows_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = NULL, *resp; - char* host; - char* port; int s; size_t i; grpc_error* error = GRPC_ERROR_NONE; /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(name, &host, &port); if (host == NULL) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -80,7 +80,7 @@ static grpc_error* windows_blocking_resolve_address( gpr_free(msg); goto done; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } /* Call getaddrinfo */ @@ -90,7 +90,7 @@ static grpc_error* windows_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); + s = getaddrinfo(host.get(), port.get(), &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { error = GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo"); @@ -122,8 +122,6 @@ static grpc_error* windows_blocking_resolve_address( } done: - gpr_free(host); - gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 0839bdfef2d..baadf1da99e 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -28,8 +28,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" @@ -181,15 +181,17 @@ int grpc_sockaddr_to_string(char** out, } if (ip != nullptr && grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != nullptr) { + grpc_core::UniquePtr tmp_out; if (sin6_scope_id != 0) { char* host_with_scope; /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */ gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id); - ret = gpr_join_host_port(out, host_with_scope, port); + ret = grpc_core::JoinHostPort(&tmp_out, host_with_scope, port); gpr_free(host_with_scope); } else { - ret = gpr_join_host_port(out, ntop_buf, port); + ret = grpc_core::JoinHostPort(&tmp_out, ntop_buf, port); } + *out = tmp_out.release(); } else { ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); } diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 2101651b33f..47d9f51b095 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -46,7 +46,6 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index 4b21322d746..fcad5edd222 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -34,7 +34,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/cfstream_handle.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint_cfstream.h" @@ -143,12 +143,13 @@ static void OnOpen(void* arg, grpc_error* error) { static void ParseResolvedAddress(const grpc_resolved_address* addr, CFStringRef* host, int* port) { - char *host_port, *host_string, *port_string; + char* host_port; grpc_sockaddr_to_string(&host_port, addr, 1); - gpr_split_host_port(host_port, &host_string, &port_string); - *host = CFStringCreateWithCString(NULL, host_string, kCFStringEncodingUTF8); - gpr_free(host_string); - gpr_free(port_string); + grpc_core::UniquePtr host_string; + grpc_core::UniquePtr port_string; + grpc_core::SplitHostPort(host_port, &host_string, &port_string); + *host = + CFStringCreateWithCString(NULL, host_string.get(), kCFStringEncodingUTF8); gpr_free(host_port); *port = grpc_sockaddr_get_port(addr); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 38b1f856d52..79908601130 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -108,10 +108,11 @@ class grpc_alts_channel_security_connector final return strcmp(target_name_, other->target_name_); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host == nullptr || strcmp(host, target_name_) != 0) { + if (host.empty() || host != target_name_) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "ALTS call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index c55fd34d0e2..940c2ac5ee5 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -31,8 +31,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -102,39 +102,35 @@ class grpc_fake_channel_security_connector final tsi_create_fake_handshaker(/*is_client=*/true), this)); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(target_, &target_hostname, &target_ignored_port); + grpc_core::StringView authority_hostname; + grpc_core::StringView authority_ignored_port; + grpc_core::StringView target_hostname; + grpc_core::StringView target_ignored_port; + grpc_core::SplitHostPort(host, &authority_hostname, + &authority_ignored_port); + grpc_core::SplitHostPort(target_, &target_hostname, &target_ignored_port); if (target_name_override_ != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(target_name_override_, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { + grpc_core::StringView fake_security_target_name_override_hostname; + grpc_core::StringView fake_security_target_name_override_ignored_port; + grpc_core::SplitHostPort( + target_name_override_, &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (authority_hostname != fake_security_target_name_override_hostname) { gpr_log(GPR_ERROR, "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); + host.data(), + fake_security_target_name_override_hostname.data()); abort(); } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); + } else if (authority_hostname != target_hostname) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", host.data(), + target_); abort(); } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); return true; } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index c1a101d4ab8..5b777009d34 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -156,10 +156,11 @@ class grpc_local_channel_security_connector final creds->connect_type()); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host == nullptr || strcmp(host, target_name_) != 0) { + if (host.empty() || host != target_name_) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "local call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 47c0ad5aa3d..2c7c982e719 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index f71ee54402d..e5ced44638b 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -98,7 +98,7 @@ class grpc_channel_security_connector : public grpc_security_connector { /// Returns true if completed synchronously, in which case \a error will /// be set to indicate the result. Otherwise, \a on_call_host_checked /// will be invoked when complete. - virtual bool check_call_host(const char* host, + virtual bool check_call_host(grpc_core::StringView host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) GRPC_ABSTRACT; diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index f920dc6046d..97c04cafce4 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -75,15 +75,14 @@ class grpc_ssl_channel_security_connector final ? nullptr : gpr_strdup(overridden_target_name)), verify_options_(&config->verify_options) { - char* port; - gpr_split_host_port(target_name, &target_name_, &port); - gpr_free(port); + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(target_name, &host, &port); + target_name_ = host.dup(); } ~grpc_ssl_channel_security_connector() override { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); - if (target_name_ != nullptr) gpr_free(target_name_); - if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); } grpc_security_status InitializeHandshakerFactory( @@ -123,8 +122,8 @@ class grpc_ssl_channel_security_connector final tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_ - : target_name_, + overridden_target_name_ != nullptr ? overridden_target_name_.get() + : target_name_.get(), &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -139,8 +138,8 @@ class grpc_ssl_channel_security_connector final grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_ - : target_name_; + ? overridden_target_name_.get() + : target_name_.get(); grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); if (error == GRPC_ERROR_NONE && verify_options_->verify_peer_callback != nullptr) { @@ -175,17 +174,18 @@ class grpc_ssl_channel_security_connector final reinterpret_cast(other_sc); int c = channel_security_connector_cmp(other); if (c != 0) return c; - c = strcmp(target_name_, other->target_name_); + c = strcmp(target_name_.get(), other->target_name_.get()); if (c != 0) return c; return (overridden_target_name_ == nullptr || other->overridden_target_name_ == nullptr) - ? GPR_ICMP(overridden_target_name_, - other->overridden_target_name_) - : strcmp(overridden_target_name_, - other->overridden_target_name_); + ? GPR_ICMP(overridden_target_name_.get(), + other->overridden_target_name_.get()) + : strcmp(overridden_target_name_.get(), + other->overridden_target_name_.get()); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { grpc_security_status status = GRPC_SECURITY_ERROR; @@ -194,7 +194,7 @@ class grpc_ssl_channel_security_connector final /* If the target name was overridden, then the original target_name was 'checked' transitively during the previous peer check at the end of the handshake. */ - if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { + if (overridden_target_name_ != nullptr && host == target_name_.get()) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -212,8 +212,8 @@ class grpc_ssl_channel_security_connector final private: tsi_ssl_client_handshaker_factory* client_handshaker_factory_; - char* target_name_; - char* overridden_target_name_; + grpc_core::UniquePtr target_name_; + grpc_core::UniquePtr overridden_target_name_; const verify_peer_options* verify_options_; }; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index cb0d5437988..ebb4a3f9ee8 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,9 +27,9 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" @@ -136,12 +136,13 @@ grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { return GRPC_ERROR_NONE; } -grpc_error* grpc_ssl_check_peer_name(const char* peer_name, +grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, const tsi_peer* peer) { /* Check the peer name if specified. */ - if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + if (!peer_name.empty() && !grpc_ssl_host_matches_name(peer, peer_name)) { char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", + peer_name.data()); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; @@ -149,15 +150,16 @@ grpc_error* grpc_ssl_check_peer_name(const char* peer_name, return GRPC_ERROR_NONE; } -bool grpc_ssl_check_call_host(const char* host, const char* target_name, - const char* overridden_target_name, +bool grpc_ssl_check_call_host(grpc_core::StringView host, + grpc_core::StringView target_name, + grpc_core::StringView overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { grpc_security_status status = GRPC_SECURITY_ERROR; tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - if (overridden_target_name != nullptr && strcmp(host, target_name) == 0) { + if (!overridden_target_name.empty() && host == target_name) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -179,35 +181,28 @@ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { return alpn_protocol_strings; } -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { - char* allocated_name = nullptr; - int r; - - char* ignored_port; - gpr_split_host_port(peer_name, &allocated_name, &ignored_port); - gpr_free(ignored_port); - peer_name = allocated_name; - if (!peer_name) return 0; +int grpc_ssl_host_matches_name(const tsi_peer* peer, + grpc_core::StringView peer_name) { + grpc_core::StringView allocated_name; + grpc_core::StringView ignored_port; + grpc_core::SplitHostPort(peer_name, &allocated_name, &ignored_port); + if (allocated_name.empty()) return 0; // IPv6 zone-id should not be included in comparisons. - char* const zone_id = strchr(allocated_name, '%'); - if (zone_id != nullptr) *zone_id = '\0'; - - r = tsi_ssl_peer_matches_name(peer, peer_name); - gpr_free(allocated_name); - return r; + const size_t zone_id = allocated_name.find('%'); + if (zone_id != grpc_core::StringView::npos) { + allocated_name.remove_suffix(allocated_name.size() - zone_id); + } + return tsi_ssl_peer_matches_name(peer, allocated_name); } -bool grpc_ssl_cmp_target_name(const char* target_name, - const char* other_target_name, - const char* overridden_target_name, - const char* other_overridden_target_name) { - int c = strcmp(target_name, other_target_name); +int grpc_ssl_cmp_target_name( + grpc_core::StringView target_name, grpc_core::StringView other_target_name, + grpc_core::StringView overridden_target_name, + grpc_core::StringView other_overridden_target_name) { + int c = target_name.cmp(other_target_name); if (c != 0) return c; - return (overridden_target_name == nullptr || - other_overridden_target_name == nullptr) - ? GPR_ICMP(overridden_target_name, other_overridden_target_name) - : strcmp(overridden_target_name, other_overridden_target_name); + return overridden_target_name.cmp(other_overridden_target_name); } grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 1765a344c2a..bf8c1de3aae 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -28,6 +28,7 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/ssl_transport_security.h" @@ -46,16 +47,17 @@ GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer); /* Check peer name information returned from SSL handshakes. */ -grpc_error* grpc_ssl_check_peer_name(const char* peer_name, +grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, const tsi_peer* peer); /* Compare targer_name information extracted from SSL security connectors. */ -bool grpc_ssl_cmp_target_name(const char* target_name, - const char* other_target_name, - const char* overridden_target_name, - const char* other_overridden_target_name); +int grpc_ssl_cmp_target_name( + grpc_core::StringView target_name, grpc_core::StringView other_target_name, + grpc_core::StringView overridden_target_name, + grpc_core::StringView other_overridden_target_name); /* Check the host that will be set for a call is acceptable.*/ -bool grpc_ssl_check_call_host(const char* host, const char* target_name, - const char* overridden_target_name, +bool grpc_ssl_check_call_host(grpc_core::StringView host, + grpc_core::StringView target_name, + grpc_core::StringView overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error); @@ -89,7 +91,8 @@ grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( tsi_peer grpc_shallow_peer_from_ssl_auth_context( const grpc_auth_context* auth_context); void grpc_shallow_peer_destruct(tsi_peer* peer); -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); +int grpc_ssl_host_matches_name(const tsi_peer* peer, + grpc_core::StringView peer_name); /* --- Default SSL Root Store. --- */ namespace grpc_core { diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc index ebf9c905079..5853de4fc13 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -28,7 +28,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" #include "src/core/lib/security/credentials/tls/spiffe_credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -105,18 +105,13 @@ SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( ? nullptr : gpr_strdup(overridden_target_name)) { check_arg_ = ServerAuthorizationCheckArgCreate(this); - char* port; - gpr_split_host_port(target_name, &target_name_, &port); - gpr_free(port); + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(target_name, &host, &port); + target_name_ = host.dup(); } SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { - if (target_name_ != nullptr) { - gpr_free(target_name_); - } - if (overridden_target_name_ != nullptr) { - gpr_free(overridden_target_name_); - } if (client_handshaker_factory_ != nullptr) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); } @@ -130,8 +125,8 @@ void SpiffeChannelSecurityConnector::add_handshakers( tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_ - : target_name_, + overridden_target_name_ != nullptr ? overridden_target_name_.get() + : target_name_.get(), &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -147,8 +142,8 @@ void SpiffeChannelSecurityConnector::check_peer( grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_ - : target_name_; + ? overridden_target_name_.get() + : target_name_.get(); grpc_error* error = grpc_ssl_check_alpn(&peer); if (error != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_peer_checked, error); @@ -203,16 +198,17 @@ int SpiffeChannelSecurityConnector::cmp( if (c != 0) { return c; } - return grpc_ssl_cmp_target_name(target_name_, other->target_name_, - overridden_target_name_, - other->overridden_target_name_); + return grpc_ssl_cmp_target_name(target_name_.get(), other->target_name_.get(), + overridden_target_name_.get(), + other->overridden_target_name_.get()); } bool SpiffeChannelSecurityConnector::check_call_host( - const char* host, grpc_auth_context* auth_context, + grpc_core::StringView host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { - return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, - auth_context, on_call_host_checked, error); + return grpc_ssl_check_call_host(host, target_name_.get(), + overridden_target_name_.get(), auth_context, + on_call_host_checked, error); } void SpiffeChannelSecurityConnector::cancel_check_call_host( diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h index 56972153e07..5ea00ee85b6 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -53,7 +53,8 @@ class SpiffeChannelSecurityConnector final int cmp(const grpc_security_connector* other_sc) const override; - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override; @@ -83,8 +84,8 @@ class SpiffeChannelSecurityConnector final grpc_tls_server_authorization_check_arg* arg); grpc_closure* on_peer_checked_; - char* target_name_; - char* overridden_target_name_; + grpc_core::UniquePtr target_name_; + grpc_core::UniquePtr overridden_target_name_; tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; grpc_tls_server_authorization_check_arg* check_arg_; }; diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 1062fc2f4fa..33343d276eb 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -346,7 +346,7 @@ static void auth_start_transport_stream_op_batch( GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch, grpc_schedule_on_exec_ctx); - char* call_host = grpc_slice_to_c_string(calld->host); + grpc_core::StringView call_host(calld->host); grpc_error* error = GRPC_ERROR_NONE; if (chand->security_connector->check_call_host( call_host, chand->auth_context.get(), @@ -360,7 +360,6 @@ static void auth_start_transport_stream_op_batch( &calld->check_call_host_cancel_closure, cancel_check_call_host, elem, grpc_schedule_on_exec_ctx)); } - gpr_free(call_host); return; /* early exit */ } } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 1b7e58d3ce0..0d28303e7dd 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -30,7 +30,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 25ae2cee285..d3c8982c847 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -233,11 +233,10 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) { /* Returns 1 if name looks like an IP address, 0 otherwise. This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ -static int looks_like_ip_address(const char* name) { - size_t i; +static int looks_like_ip_address(grpc_core::StringView name) { size_t dot_count = 0; size_t num_size = 0; - for (i = 0; i < strlen(name); i++) { + for (size_t i = 0; i < name.size(); ++i) { if (name[i] == ':') { /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ return 1; @@ -1506,52 +1505,46 @@ static void tsi_ssl_server_handshaker_factory_destroy( gpr_free(self); } -static int does_entry_match_name(const char* entry, size_t entry_length, - const char* name) { - const char* dot; - const char* name_subdomain = nullptr; - size_t name_length = strlen(name); - size_t name_subdomain_length; - if (entry_length == 0) return 0; +static int does_entry_match_name(grpc_core::StringView entry, + grpc_core::StringView name) { + if (entry.empty()) return 0; /* Take care of '.' terminations. */ - if (name[name_length - 1] == '.') { - name_length--; + if (name.back() == '.') { + name.remove_suffix(1); } - if (entry[entry_length - 1] == '.') { - entry_length--; - if (entry_length == 0) return 0; + if (entry.back() == '.') { + entry.remove_suffix(1); + if (entry.empty()) return 0; } - if ((name_length == entry_length) && - strncmp(name, entry, entry_length) == 0) { + if (name == entry) { return 1; /* Perfect match. */ } - if (entry[0] != '*') return 0; + if (entry.front() != '*') return 0; /* Wildchar subdomain matching. */ - if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ + if (entry.size() < 3 || entry[1] != '.') { /* At least *.x */ gpr_log(GPR_ERROR, "Invalid wildchar entry."); return 0; } - name_subdomain = strchr(name, '.'); - if (name_subdomain == nullptr) return 0; - name_subdomain_length = strlen(name_subdomain); - if (name_subdomain_length < 2) return 0; - name_subdomain++; /* Starts after the dot. */ - name_subdomain_length--; - entry += 2; /* Remove *. */ - entry_length -= 2; - dot = strchr(name_subdomain, '.'); - if ((dot == nullptr) || (dot == &name_subdomain[name_subdomain_length - 1])) { - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); + size_t name_subdomain_pos = name.find('.'); + if (name_subdomain_pos == grpc_core::StringView::npos) return 0; + if (name_subdomain_pos >= name.size() - 2) return 0; + grpc_core::StringView name_subdomain = + name.substr(name_subdomain_pos + 1); /* Starts after the dot. */ + entry.remove_prefix(2); /* Remove *. */ + size_t dot = name_subdomain.find('.'); + if (dot == grpc_core::StringView::npos || dot == name_subdomain.size() - 1) { + grpc_core::UniquePtr name_subdomain_cstr(name_subdomain.dup()); + gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", + name_subdomain_cstr.get()); return 0; } - if (name_subdomain[name_subdomain_length - 1] == '.') { - name_subdomain_length--; + if (name_subdomain.back() == '.') { + name_subdomain.remove_suffix(1); } - return ((entry_length > 0) && (name_subdomain_length == entry_length) && - strncmp(entry, name_subdomain, entry_length) == 0); + return !entry.empty() && name_subdomain == entry; } static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, @@ -1919,7 +1912,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( /* --- tsi_ssl utils. --- */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { +int tsi_ssl_peer_matches_name(const tsi_peer* peer, + grpc_core::StringView name) { size_t i = 0; size_t san_count = 0; const tsi_peer_property* cn_property = nullptr; @@ -1933,13 +1927,10 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { san_count++; - if (!like_ip && does_entry_match_name(property->value.data, - property->value.length, name)) { + grpc_core::StringView entry(property->value.data, property->value.length); + if (!like_ip && does_entry_match_name(entry, name)) { return 1; - } else if (like_ip && - strncmp(name, property->value.data, property->value.length) == - 0 && - strlen(name) == property->value.length) { + } else if (like_ip && name == entry) { /* IP Addresses are exact matches only. */ return 1; } @@ -1951,8 +1942,9 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { /* If there's no SAN, try the CN, but only if its not like an IP Address */ if (san_count == 0 && cn_property != nullptr && !like_ip) { - if (does_entry_match_name(cn_property->value.data, - cn_property->value.length, name)) { + if (does_entry_match_name(grpc_core::StringView(cn_property->value.data, + cn_property->value.length), + name)) { return 1; } } diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 769949e4aad..0203141e56e 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/string_view.h" #include "src/core/tsi/transport_security_interface.h" /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ @@ -306,7 +307,7 @@ void tsi_ssl_server_handshaker_factory_unref( - handle mixed case. - handle %encoded chars. - handle public suffix wildchar more strictly (e.g. *.co.uk) */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name); +int tsi_ssl_peer_matches_name(const tsi_peer* peer, grpc_core::StringView name); /* --- Testing support. --- diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index a24734024dc..fbcd4f888d4 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -37,9 +37,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -51,19 +51,18 @@ #import "../ConfigureCronet.h" -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data)); + fullstack_secure_fixture_data *ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); + grpc_core::JoinHostPort(&ffd->localaddr, "127.0.0.1", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(NULL); @@ -103,8 +102,7 @@ static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 2473cf612be..4e2e70f1512 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -33,9 +33,9 @@ #import "src/core/lib/channel/channel_args.h" #import "src/core/lib/gpr/env.h" -#import "src/core/lib/gpr/host_port.h" #import "src/core/lib/gpr/string.h" #import "src/core/lib/gpr/tmpfile.h" +#import "src/core/lib/gprpp/host_port.h" #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" @@ -133,11 +133,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -264,11 +264,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), args, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2619ccf9740..c7caee551ce 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -27,7 +27,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -54,6 +53,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 8dd55f64944..deae9072613 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,8 +25,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -144,7 +145,9 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); @@ -153,7 +156,6 @@ int main(int argc, char** argv) { run_test(args[2], i); grpc_shutdown(); } - gpr_free(args[2]); gpr_subprocess_interrupt(svr); status = gpr_subprocess_join(svr); diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc index bfafa745178..071fb88b734 100644 --- a/test/core/client_channel/parse_address_with_named_scope_id_test.cc +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -30,7 +30,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_config.h" @@ -60,20 +61,20 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo( struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { grpc_uri* uri = grpc_uri_parse(uri_text, 0); - char* host = nullptr; - char* port = nullptr; - gpr_split_host_port(uri->path, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(uri->path, &host, &port); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; struct addrinfo* result; - int res = getaddrinfo(host, port, &hints, &result); + int res = getaddrinfo(host.get(), port.get(), &hints, &result); if (res != 0) { gpr_log(GPR_ERROR, - "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, - port, res); + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", + host.get(), port.get(), res); abort(); } size_t num_addrs_from_getaddrinfo = 0; @@ -86,8 +87,6 @@ struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { *reinterpret_cast(result->ai_addr); // Cleanup freeaddrinfo(result); - gpr_free(host); - gpr_free(port); grpc_uri_destroy(uri); return out; } diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 2d74b6b77b3..db480463b68 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -29,8 +29,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -71,7 +71,7 @@ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 struct rpc_state { - char* target; + grpc_core::UniquePtr target; grpc_completion_queue* cq; grpc_channel* channel; grpc_call* call; @@ -165,8 +165,9 @@ static void start_rpc(int target_port, grpc_status_code expected_status, state.cq = grpc_completion_queue_create_for_next(nullptr); cqv = cq_verifier_create(state.cq); - gpr_join_host_port(&state.target, "127.0.0.1", target_port); - state.channel = grpc_insecure_channel_create(state.target, nullptr, nullptr); + grpc_core::JoinHostPort(&state.target, "127.0.0.1", target_port); + state.channel = + grpc_insecure_channel_create(state.target.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("localhost"); state.call = grpc_channel_create_call( state.channel, nullptr, GRPC_PROPAGATE_DEFAULTS, state.cq, @@ -230,7 +231,7 @@ static void cleanup_rpc() { } while (ev.type != GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(state.cq); grpc_channel_destroy(state.channel); - gpr_free(state.target); + state.target.reset(); } typedef struct { diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 446e7b045a1..3bb6d2e23b6 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -24,7 +24,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" @@ -77,10 +77,10 @@ static void run_test(bool wait_for_ready, bool use_service_config) { /* create a call, channel to a port which will refuse connection */ int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, "127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr); - chan = grpc_insecure_channel_create(addr, args, nullptr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); + gpr_log(GPR_INFO, "server: %s", addr.get()); + chan = grpc_insecure_channel_create(addr.get(), args, nullptr); grpc_slice host = grpc_slice_from_static_string("nonexistant"); gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); call = @@ -88,8 +88,6 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_slice_from_static_string("/service/method"), &host, deadline, nullptr); - gpr_free(addr); - memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index 330af8fce07..cb49e0030b4 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -28,8 +28,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -70,8 +70,6 @@ static void log_resolved_addrs(const char* label, const char* hostname) { void test_connect(const char* server_host, const char* client_host, int port, int expect_ok) { - char* client_hostport; - char* server_hostport; grpc_channel* client; grpc_server* server; grpc_completion_queue* cq; @@ -99,7 +97,8 @@ void test_connect(const char* server_host, const char* client_host, int port, picked_port = 1; } - gpr_join_host_port(&server_hostport, server_host, port); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, server_host, port); grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); @@ -111,7 +110,7 @@ void test_connect(const char* server_host, const char* client_host, int port, server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(server, cq, nullptr); GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port( - server, server_hostport)) > 0); + server, server_hostport.get())) > 0); if (port == 0) { port = got_port; } else { @@ -121,6 +120,7 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv = cq_verifier_create(cq); /* Create client. */ + grpc_core::UniquePtr client_hostport; if (client_host[0] == 'i') { /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */ size_t i; @@ -139,8 +139,8 @@ void test_connect(const char* server_host, const char* client_host, int port, gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port); gpr_free(uri_part_str); } - client_hostport = gpr_strjoin_sep((const char**)hosts_with_port, - uri_parts.count, ",", nullptr); + client_hostport.reset(gpr_strjoin_sep((const char**)hosts_with_port, + uri_parts.count, ",", nullptr)); for (i = 0; i < uri_parts.count; i++) { gpr_free(hosts_with_port[i]); } @@ -148,18 +148,17 @@ void test_connect(const char* server_host, const char* client_host, int port, grpc_slice_buffer_destroy(&uri_parts); grpc_slice_unref(uri_slice); } else { - gpr_join_host_port(&client_hostport, client_host, port); + grpc_core::JoinHostPort(&client_hostport, client_host, port); } - client = grpc_insecure_channel_create(client_hostport, nullptr, nullptr); + client = + grpc_insecure_channel_create(client_hostport.get(), nullptr, nullptr); gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport, client_hostport, expect_ok ? "success" : "failure"); + server_hostport.get(), client_hostport.get(), + expect_ok ? "success" : "failure"); log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); - gpr_free(client_hostport); - gpr_free(server_hostport); - if (expect_ok) { /* Normal deadline, shouldn't be reached. */ deadline = grpc_timeout_milliseconds_to_deadline(60000); diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 60442ddcc77..72cb96138e1 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -29,25 +29,23 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -71,7 +69,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, grpc_arg arg = make_census_enable_arg(); client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); { grpc_core::ExecCtx exec_ctx; @@ -94,15 +92,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_channel_args_destroy(server_args); } grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 01e5ae1b7b5..dd0c1fe0201 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -30,28 +30,29 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/compression/compression_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_compression_fixture_data { - char* localaddr; - grpc_channel_args* client_args_compression; - grpc_channel_args* server_args_compression; -} fullstack_compression_fixture_data; +struct fullstack_compression_fixture_data { + ~fullstack_compression_fixture_data() { + grpc_channel_args_destroy(client_args_compression); + grpc_channel_args_destroy(server_args_compression); + } + grpc_core::UniquePtr localaddr; + grpc_channel_args* client_args_compression = nullptr; + grpc_channel_args* server_args_compression = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_compression_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_compression_fixture_data))); - memset(ffd, 0, sizeof(fullstack_compression_fixture_data)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::New(); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; @@ -73,7 +74,7 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f, grpc_channel_args_set_channel_default_compression_algorithm( client_args, GRPC_COMPRESS_GZIP); f->client = grpc_insecure_channel_create( - ffd->localaddr, ffd->client_args_compression, nullptr); + ffd->localaddr.get(), ffd->client_args_compression, nullptr); } void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, @@ -92,7 +93,8 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(ffd->server_args_compression, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } @@ -100,10 +102,7 @@ void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; fullstack_compression_fixture_data* ffd = static_cast(f->fixture_data); - grpc_channel_args_destroy(ffd->client_args_compression); - grpc_channel_args_destroy(ffd->server_args_compression); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index ad83aab39f4..1375549ed6c 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -25,26 +25,24 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); - + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,8 +64,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -82,7 +80,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -91,8 +89,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_fake_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index 6d559c4e516..ac4913674f0 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -33,26 +33,25 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index b8dbe261183..04de2a20182 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -34,25 +34,24 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index cb0f7d275b3..8cfba4587e0 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -30,7 +30,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -39,24 +39,20 @@ static char* workarounds_arg[GRPC_MAX_WORKAROUND_ID] = { const_cast(GRPC_ARG_WORKAROUND_CRONET_COMPRESSION)}; -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -65,7 +61,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -88,7 +84,8 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args_new, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); grpc_channel_args_destroy(server_args_new); } @@ -96,8 +93,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index c0d21288c7e..a3f2f25db5f 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -28,25 +28,24 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -60,7 +59,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -73,15 +72,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 9b6a81494e1..18ba0e7f847 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -30,26 +30,26 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* server_addr; - grpc_end2end_http_proxy* proxy; -} fullstack_fixture_data; +struct fullstack_fixture_data { + ~fullstack_fixture_data() { grpc_end2end_http_proxy_destroy(proxy); } + grpc_core::UniquePtr server_addr; + grpc_end2end_http_proxy* proxy = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; memset(&f, 0, sizeof(f)); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); const int server_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&ffd->server_addr, "localhost", server_port); + grpc_core::JoinHostPort(&ffd->server_addr, "localhost", server_port); /* Passing client_args to proxy_create for the case of checking for proxy auth */ @@ -81,8 +81,8 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, } gpr_setenv("http_proxy", proxy_uri); gpr_free(proxy_uri); - f->client = - grpc_insecure_channel_create(ffd->server_addr, client_args, nullptr); + f->client = grpc_insecure_channel_create(ffd->server_addr.get(), client_args, + nullptr); GPR_ASSERT(f->client); } @@ -95,16 +95,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->server_addr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->server_addr); - grpc_end2end_http_proxy_destroy(ffd->proxy); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc index f6996bf6be3..e27844be2df 100644 --- a/test/core/end2end/fixtures/h2_local_ipv4.cc +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "127.0.0.1", port); diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc index e360727ca82..91acaa347f6 100644 --- a/test/core/end2end/fixtures/h2_local_ipv6.cc +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "[::1]", port); diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc index f1bce213dc2..6c748896760 100644 --- a/test/core/end2end/fixtures/h2_local_uds.cc +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -30,10 +30,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); - gpr_asprintf( - &static_cast(f.fixture_data) - ->localaddr, - "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + char* out = nullptr; + gpr_asprintf(&out, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + static_cast(f.fixture_data) + ->localaddr.reset(out); return f; } diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 113a6b11732..513fded4b62 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -25,7 +25,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -36,9 +36,9 @@ static const char oauth2_md[] = "Bearer aaslkfjs424535asdf"; static const char* client_identity_property_name = "smurf_name"; static const char* client_identity = "Brainy Smurf"; -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static const grpc_metadata* find_metadata(const grpc_metadata* md, size_t md_count, const char* key, @@ -95,16 +95,12 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -113,8 +109,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -129,7 +125,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -138,8 +134,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index e334396ea7c..f0ada89d14d 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/proxy.h" diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index cdf091bac10..4352ef640cd 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -28,9 +28,9 @@ #include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/security/credentials/credentials.h" @@ -42,10 +42,15 @@ typedef grpc_core::InlinedVector ThreadList; -typedef struct fullstack_secure_fixture_data { - char* localaddr; +struct fullstack_secure_fixture_data { + ~fullstack_secure_fixture_data() { + for (size_t ind = 0; ind < thd_list.size(); ind++) { + thd_list[ind].Join(); + } + } + grpc_core::UniquePtr localaddr; ThreadList thd_list; -} fullstack_secure_fixture_data; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { @@ -54,7 +59,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( fullstack_secure_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); @@ -74,8 +79,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -90,7 +95,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -99,10 +104,6 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { - ffd->thd_list[ind].Join(); - } - gpr_free(ffd->localaddr); grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 3fc9bc7f329..cb55bb72061 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,29 +25,28 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -69,8 +68,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -85,7 +84,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -94,8 +93,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 1d54a431364..2a9591845b9 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,19 +25,19 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; - bool server_credential_reloaded; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; + bool server_credential_reloaded = false; +}; static grpc_ssl_certificate_config_reload_status ssl_server_certificate_config_callback( @@ -64,10 +64,9 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -89,8 +88,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -106,7 +105,7 @@ static void chttp2_init_server_secure_fullstack( ffd->server_credential_reloaded = false; f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -115,8 +114,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index d5f695b1575..b16ffa1b8b8 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,7 +25,6 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index f251bbd28c5..2b6c73d39c7 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index 6b5513f160e..da2381aa0a0 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -31,8 +31,8 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/closure.h" @@ -53,8 +53,7 @@ struct grpc_end2end_http_proxy { grpc_end2end_http_proxy() - : proxy_name(nullptr), - server(nullptr), + : server(nullptr), channel_args(nullptr), mu(nullptr), pollset(nullptr), @@ -62,7 +61,7 @@ struct grpc_end2end_http_proxy { gpr_ref_init(&users, 1); combiner = grpc_combiner_create(); } - char* proxy_name; + grpc_core::UniquePtr proxy_name; grpc_core::Thread thd; grpc_tcp_server* server; grpc_channel_args* channel_args; @@ -532,8 +531,8 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_end2end_http_proxy* proxy = grpc_core::New(); // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name); + grpc_core::JoinHostPort(&proxy->proxy_name, "localhost", proxy_port); + gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.get()); // Create TCP server. proxy->channel_args = grpc_channel_args_copy(args); grpc_error* error = @@ -573,7 +572,6 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { proxy->thd.Join(); grpc_tcp_server_shutdown_listeners(proxy->server); grpc_tcp_server_unref(proxy->server); - gpr_free(proxy->proxy_name); grpc_channel_args_destroy(proxy->channel_args); grpc_pollset_shutdown(proxy->pollset, GRPC_CLOSURE_CREATE(destroy_pollset, proxy->pollset, @@ -584,5 +582,5 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { const char* grpc_end2end_http_proxy_get_proxy_name( grpc_end2end_http_proxy* proxy) { - return proxy->proxy_name; + return proxy->proxy_name.get(); } diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index dadf3ef455d..70cc6b05479 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/inproc/inproc_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/local_util.cc b/test/core/end2end/fixtures/local_util.cc index 5f0b0300ac0..767f3a28ef8 100644 --- a/test/core/end2end/fixtures/local_util.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -27,7 +27,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/server.h" @@ -37,8 +36,7 @@ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; grpc_end2end_local_fullstack_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -52,8 +50,8 @@ void grpc_end2end_local_chttp2_init_client_fullstack( grpc_channel_credentials* creds = grpc_local_credentials_create(type); grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -99,8 +97,8 @@ void grpc_end2end_local_chttp2_init_server_fullstack( nullptr}; grpc_server_credentials_set_auth_metadata_processor(creds, processor); } - GPR_ASSERT( - grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + creds)); grpc_server_credentials_release(creds); grpc_server_start(f->server); } @@ -109,6 +107,5 @@ void grpc_end2end_local_chttp2_tear_down_fullstack( grpc_end2end_test_fixture* f) { grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h index f133b4d977e..df204d2fab2 100644 --- a/test/core/end2end/fixtures/local_util.h +++ b/test/core/end2end/fixtures/local_util.h @@ -22,9 +22,9 @@ #include "src/core/lib/surface/channel.h" -typedef struct grpc_end2end_local_fullstack_fixture_data { - char* localaddr; -} grpc_end2end_local_fullstack_fixture_data; +struct grpc_end2end_local_fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; /* Utility functions shared by h2_local tests. */ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index 869b6e846d3..4ae7450b0df 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,16 +24,15 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "test/core/util/port.h" struct grpc_end2end_proxy { grpc_end2end_proxy() - : proxy_port(nullptr), - server_port(nullptr), - cq(nullptr), + : cq(nullptr), server(nullptr), client(nullptr), shutdown(false), @@ -42,8 +41,8 @@ struct grpc_end2end_proxy { memset(&new_call_metadata, 0, sizeof(new_call_metadata)); } grpc_core::Thread thd; - char* proxy_port; - char* server_port; + grpc_core::UniquePtr proxy_port; + grpc_core::UniquePtr server_port; grpc_completion_queue* cq; grpc_server* server; grpc_channel* client; @@ -92,15 +91,15 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_end2end_proxy* proxy = grpc_core::New(); - gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); - gpr_join_host_port(&proxy->server_port, "localhost", server_port); + grpc_core::JoinHostPort(&proxy->proxy_port, "localhost", proxy_port); + grpc_core::JoinHostPort(&proxy->server_port, "localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port, - proxy->server_port); + gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.get(), + proxy->server_port.get()); proxy->cq = grpc_completion_queue_create_for_next(nullptr); - proxy->server = def->create_server(proxy->proxy_port, server_args); - proxy->client = def->create_client(proxy->server_port, client_args); + proxy->server = def->create_server(proxy->proxy_port.get(), server_args); + proxy->client = def->create_client(proxy->server_port.get(), client_args); grpc_server_register_completion_queue(proxy->server, proxy->cq, nullptr); grpc_server_start(proxy->server); @@ -131,8 +130,6 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_server_shutdown_and_notify(proxy->server, proxy->cq, new_closure(shutdown_complete, proxy)); proxy->thd.Join(); - gpr_free(proxy->proxy_port); - gpr_free(proxy->server_port); grpc_server_destroy(proxy->server); grpc_channel_destroy(proxy->client); grpc_completion_queue_destroy(proxy->cq); @@ -441,9 +438,9 @@ static void thread_main(void* arg) { } const char* grpc_end2end_proxy_get_client_target(grpc_end2end_proxy* proxy) { - return proxy->proxy_port; + return proxy->proxy_port.get(); } const char* grpc_end2end_proxy_get_server_port(grpc_end2end_proxy* proxy) { - return proxy->server_port; + return proxy->server_port.get(); } diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index e9285778a2d..34a9ef760b5 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -40,20 +40,19 @@ namespace grpc { namespace testing { -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -73,8 +72,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -89,7 +88,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -98,8 +97,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static int fail_server_auth_check(grpc_channel_args* server_args) { diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2d0a5e1133..6ffc138820e 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -215,19 +215,18 @@ void drain_cq(grpc_completion_queue* cq) { TEST(H2SessionReuseTest, SingleReuse) { int port = grpc_pick_unused_port_or_die(); - char* server_addr; - gpr_join_host_port(&server_addr, "localhost", port); + grpc_core::UniquePtr server_addr; + grpc_core::JoinHostPort(&server_addr, "localhost", port); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_ssl_session_cache* cache = grpc_ssl_session_cache_create_lru(16); - grpc_server* server = server_create(cq, server_addr); + grpc_server* server = server_create(cq, server_addr.get()); - do_round_trip(cq, server, server_addr, cache, false); - do_round_trip(cq, server, server_addr, cache, true); - do_round_trip(cq, server, server_addr, cache, true); + do_round_trip(cq, server, server_addr.get(), cache, false); + do_round_trip(cq, server, server_addr.get(), cache, true); + do_round_trip(cq, server, server_addr.get(), cache, true); - gpr_free(server_addr); grpc_ssl_session_cache_destroy(cache); GPR_ASSERT(grpc_completion_queue_next( diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index bd28d192984..5f920fad638 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -25,7 +25,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -54,7 +55,6 @@ static struct test_state g_state; static void prepare_test(int is_client) { int port = grpc_pick_unused_port_or_die(); - char* server_hostport; grpc_op* op; g_state.is_client = is_client; grpc_metadata_array_init(&g_state.initial_metadata_recv); @@ -77,14 +77,13 @@ static void prepare_test(int is_client) { } else { g_state.server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(g_state.server, g_state.cq, nullptr); - gpr_join_host_port(&server_hostport, "0.0.0.0", port); - grpc_server_add_insecure_http2_port(g_state.server, server_hostport); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, "0.0.0.0", port); + grpc_server_add_insecure_http2_port(g_state.server, server_hostport.get()); grpc_server_start(g_state.server); - gpr_free(server_hostport); - gpr_join_host_port(&server_hostport, "localhost", port); + grpc_core::JoinHostPort(&server_hostport, "localhost", port); g_state.chan = - grpc_insecure_channel_create(server_hostport, nullptr, nullptr); - gpr_free(server_hostport); + grpc_insecure_channel_create(server_hostport.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("bar"); g_state.call = grpc_channel_create_call( g_state.chan, nullptr, GRPC_PROPAGATE_DEFAULTS, g_state.cq, diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc index 32bc9896414..474b4fbbc3b 100644 --- a/test/core/fling/fling_stream_test.cc +++ b/test/core/fling/fling_stream_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +46,24 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-stream"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc index 3587a4acaae..3667d48f010 100644 --- a/test/core/fling/fling_test.cc +++ b/test/core/fling/fling_test.cc @@ -22,8 +22,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +47,24 @@ int main(int argc, const char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-request"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/server.cc b/test/core/fling/server.cc index cf7e2465d9e..241ac71bc7d 100644 --- a/test/core/fling/server.cc +++ b/test/core/fling/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" @@ -172,7 +172,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_event ev; call_state* s; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -199,8 +199,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -220,8 +220,8 @@ int main(int argc, char** argv) { grpc_server_register_completion_queue(server, cq, nullptr); grpc_server_start(server); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); grpc_call_details_init(&call_details); diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index 434d55e0451..c2b2576ff03 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -58,16 +58,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "host_port_test", - srcs = ["host_port_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "log_test", srcs = ["log_test.cc"], diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index cd3232addfd..5cee96a3ad2 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -64,6 +64,16 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "host_port_test", + srcs = ["host_port_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "grpc_core_map_test", srcs = ["map_test.cc"], @@ -156,6 +166,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "string_view_test", + srcs = ["string_view_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr_base", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "thd_test", srcs = ["thd_test.cc"], diff --git a/test/core/gpr/host_port_test.cc b/test/core/gprpp/host_port_test.cc similarity index 86% rename from test/core/gpr/host_port_test.cc rename to test/core/gprpp/host_port_test.cc index b01bbf4b695..3474e6dc494 100644 --- a/test/core/gpr/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -21,18 +21,17 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/test_config.h" static void join_host_port_expect(const char* host, int port, const char* expected) { - char* buf; + grpc_core::UniquePtr buf; int len; - len = gpr_join_host_port(&buf, host, port); + len = grpc_core::JoinHostPort(&buf, host, port); GPR_ASSERT(len >= 0); - GPR_ASSERT(strlen(expected) == (size_t)len); - GPR_ASSERT(strcmp(expected, buf) == 0); - gpr_free(buf); + GPR_ASSERT(strlen(expected) == static_cast(len)); + GPR_ASSERT(strcmp(expected, buf.get()) == 0); } static void test_join_host_port(void) { diff --git a/test/core/gprpp/string_view_test.cc b/test/core/gprpp/string_view_test.cc new file mode 100644 index 00000000000..1c8adb1db14 --- /dev/null +++ b/test/core/gprpp/string_view_test.cc @@ -0,0 +1,163 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/string_view.h" + +#include +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +TEST(StringViewTest, Empty) { + grpc_core::StringView empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(empty.size(), 0lu); + + grpc_core::StringView empty_buf(""); + EXPECT_TRUE(empty_buf.empty()); + EXPECT_EQ(empty_buf.size(), 0lu); + + grpc_core::StringView empty_trimmed("foo", 0); + EXPECT_TRUE(empty_trimmed.empty()); + EXPECT_EQ(empty_trimmed.size(), 0lu); + + grpc_core::StringView empty_slice(grpc_empty_slice()); + EXPECT_TRUE(empty_slice.empty()); + EXPECT_EQ(empty_slice.size(), 0lu); +} + +TEST(StringViewTest, Size) { + constexpr char kStr[] = "foo"; + grpc_core::StringView str1(kStr); + EXPECT_EQ(str1.size(), strlen(kStr)); + grpc_core::StringView str2(kStr, 2); + EXPECT_EQ(str2.size(), 2lu); +} + +TEST(StringViewTest, Data) { + constexpr char kStr[] = "foo-bar"; + grpc_core::StringView str(kStr); + EXPECT_EQ(str.size(), strlen(kStr)); + for (size_t i = 0; i < strlen(kStr); ++i) { + EXPECT_EQ(str[i], kStr[i]); + } +} + +TEST(StringViewTest, Slice) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Dup) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + grpc_core::UniquePtr dup = slice.dup(); + EXPECT_EQ(0, strcmp(kStr, dup.get())); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Eq) { + constexpr char kStr1[] = "foo"; + constexpr char kStr2[] = "bar"; + grpc_core::StringView str1(kStr1); + EXPECT_EQ(kStr1, str1); + EXPECT_EQ(str1, kStr1); + grpc_core::StringView slice1(grpc_slice_from_static_string(kStr1)); + EXPECT_EQ(slice1, str1); + EXPECT_EQ(str1, slice1); + EXPECT_NE(slice1, kStr2); + EXPECT_NE(kStr2, slice1); + grpc_core::StringView slice2(grpc_slice_from_static_string(kStr2)); + EXPECT_NE(slice2, str1); + EXPECT_NE(str1, slice2); +} + +TEST(StringViewTest, Cmp) { + constexpr char kStr1[] = "abc"; + constexpr char kStr2[] = "abd"; + constexpr char kStr3[] = "abcd"; + grpc_core::StringView str1(kStr1); + grpc_core::StringView str2(kStr2); + grpc_core::StringView str3(kStr3); + EXPECT_EQ(str1.cmp(str1), 0); + EXPECT_LT(str1.cmp(str2), 0); + EXPECT_LT(str1.cmp(str3), 0); + EXPECT_EQ(str2.cmp(str2), 0); + EXPECT_GT(str2.cmp(str1), 0); + EXPECT_GT(str2.cmp(str3), 0); + EXPECT_EQ(str3.cmp(str3), 0); + EXPECT_GT(str3.cmp(str1), 0); + EXPECT_LT(str3.cmp(str2), 0); +} + +TEST(StringViewTest, RemovePrefix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_prefix(1); + EXPECT_EQ("bcd", str); + str.remove_prefix(2); + EXPECT_EQ("d", str); + str.remove_prefix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, RemoveSuffix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_suffix(1); + EXPECT_EQ("abc", str); + str.remove_suffix(2); + EXPECT_EQ("a", str); + str.remove_suffix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, Substring) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + EXPECT_EQ("bcd", str.substr(1)); + EXPECT_EQ("bc", str.substr(1, 2)); +} + +TEST(StringViewTest, Find) { + // Passing StringView::npos directly to GTEST macros result in link errors. + // Store the value in a local variable and use it in the test. + const size_t npos = grpc_core::StringView::npos; + constexpr char kStr[] = "abacad"; + grpc_core::StringView str(kStr); + EXPECT_EQ(0ul, str.find('a')); + EXPECT_EQ(2ul, str.find('a', 1)); + EXPECT_EQ(4ul, str.find('a', 3)); + EXPECT_EQ(1ul, str.find('b')); + EXPECT_EQ(npos, str.find('b', 2)); + EXPECT_EQ(npos, str.find('z')); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc index 5c35b4e1d36..5df8af5658b 100644 --- a/test/core/memory_usage/memory_usage_test.cc +++ b/test/core/memory_usage/memory_usage_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,22 +46,23 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/memory_usage_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/memory_usage_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--warmup=1000"); args[4] = const_cast("--benchmark=9000"); cli = gpr_subprocess_create(5, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6fb14fa31a0..ecdf17925ec 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -149,7 +149,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_memory_counters_init(); grpc_event ev; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -174,8 +174,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -202,8 +202,8 @@ int main(int argc, char** argv) { struct grpc_memory_counters after_server_create = grpc_memory_counters_snapshot(); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); // initialize call instances for (int i = 0; i < static_cast(sizeof(calls) / sizeof(fling_call)); diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 454cbd5747e..2c9b0d9aaed 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -22,7 +22,8 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -66,13 +67,11 @@ static void channel_idle_poll_for_timeout(grpc_channel* channel, static void run_timeouts_test(const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then let it time out */ @@ -111,7 +110,6 @@ static void run_timeouts_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } /* An edge scenario; sets channel state to explicitly, and outside @@ -120,13 +118,11 @@ static void run_channel_shutdown_before_timeout_test( const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then shut down the channel before the timer goes off */ @@ -154,7 +150,6 @@ static void run_channel_shutdown_before_timeout_test( grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static grpc_channel* insecure_test_create_channel(const char* addr) { diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 3f9a7baf98b..46c4a24f5ed 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -22,7 +22,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -56,11 +56,11 @@ static void run_test(const test_fixture* fixture) { grpc_init(); - char* addr; - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); grpc_server* server = grpc_server_create(nullptr, nullptr); - fixture->add_server_port(server, addr); + fixture->add_server_port(server, addr.get()); grpc_completion_queue* server_cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, server_cq, nullptr); @@ -73,7 +73,7 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_channel* channels[NUM_CONNECTIONS]; for (size_t i = 0; i < NUM_CONNECTIONS; i++) { - channels[i] = fixture->create_channel(addr); + channels[i] = fixture->create_channel(addr.get()); gpr_timespec connect_deadline = grpc_timeout_seconds_to_deadline(30); grpc_connectivity_state state; @@ -116,7 +116,6 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static void insecure_test_add_port(grpc_server* server, const char* addr) { diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index ffb7f14f987..a88362e13b0 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/tsi/fake_transport_security.h" @@ -47,17 +47,17 @@ void test_add_same_port_twice() { grpc_channel_args args = {1, &a}; int port = grpc_pick_unused_port_or_die(); - char* addr = nullptr; + grpc_core::UniquePtr addr; grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server* server = grpc_server_create(&args, nullptr); grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - gpr_join_host_port(&addr, "localhost", port); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds) == 0); + grpc_core::JoinHostPort(&addr, "localhost", port); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds) == 0); grpc_server_credentials_release(fake_creds); - gpr_free(addr); grpc_server_shutdown_and_notify(server, cq, nullptr); grpc_completion_queue_pluck(cq, nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index 2fc166546b0..185a6757743 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/port.h" @@ -106,18 +106,19 @@ void test_bind_server_twice(void) { void test_bind_server_to_addr(const char* host, bool secure) { int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, host, port); - gpr_log(GPR_INFO, "Test bind to %s", addr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, host, port); + gpr_log(GPR_INFO, "Test bind to %s", addr.get()); grpc_server* server = grpc_server_create(nullptr, nullptr); if (secure) { grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); grpc_server_credentials_release(fake_creds); } else { - GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr)); + GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr.get())); } grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, cq, nullptr); @@ -126,7 +127,6 @@ void test_bind_server_to_addr(const char* host, bool secure) { grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), nullptr); grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - gpr_free(addr); } static int external_dns_works(const char* host) { diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index 144ad64f095..03c088db772 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -25,7 +25,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 170584df2b9..d7803e53555 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -28,7 +28,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index 8e45b877212..e0bacb3cfd6 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -32,7 +32,6 @@ #include "test/core/util/port.h" #include "test/cpp/util/test_config.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_utils_posix.h" diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index affc75bc634..a3d9936606d 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -40,8 +40,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -64,30 +64,28 @@ struct TestAddress { }; grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) { - char* host; - char* port; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_resolved_address resolved_addr; - gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port); + grpc_core::SplitHostPort(test_addr.dest_addr.c_str(), &host, &port); if (test_addr.family == AF_INET) { sockaddr_in in_dest; memset(&in_dest, 0, sizeof(sockaddr_in)); - in_dest.sin_port = htons(atoi(port)); + in_dest.sin_port = htons(atoi(port.get())); in_dest.sin_family = AF_INET; - GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET, host.get(), &in_dest.sin_addr) == 1); memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in)); resolved_addr.len = sizeof(sockaddr_in); } else { GPR_ASSERT(test_addr.family == AF_INET6); sockaddr_in6 in6_dest; memset(&in6_dest, 0, sizeof(sockaddr_in6)); - in6_dest.sin6_port = htons(atoi(port)); + in6_dest.sin6_port = htons(atoi(port.get())); in6_dest.sin6_family = AF_INET6; - GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET6, host.get(), &in6_dest.sin6_addr) == 1); memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6)); resolved_addr.len = sizeof(sockaddr_in6); } - gpr_free(host); - gpr_free(port); return resolved_addr; } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 667011ae291..2d1a13d25a6 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/thd.h" diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 6cea8143907..67ed307d2d7 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,8 +46,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" @@ -506,10 +506,10 @@ int g_fake_non_responsive_dns_server_port = -1; void InjectBrokenNameServerList(ares_channel channel) { struct ares_addr_port_node dns_server_addrs[2]; memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); - char* unused_host; - char* local_dns_server_port; - GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), - &unused_host, &local_dns_server_port)); + grpc_core::UniquePtr unused_host; + grpc_core::UniquePtr local_dns_server_port; + GPR_ASSERT(grpc_core::SplitHostPort(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); gpr_log(GPR_DEBUG, "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " "Good server address:%s", @@ -528,12 +528,10 @@ void InjectBrokenNameServerList(ares_channel channel) { dns_server_addrs[1].family = AF_INET; ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; - dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); - dns_server_addrs[1].udp_port = atoi(local_dns_server_port); + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.get()); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port.get()); dns_server_addrs[1].next = nullptr; GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); - gpr_free(local_dns_server_port); - gpr_free(unused_host); } void StartResolvingLocked(void* arg, grpc_error* unused) { diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 668d9abf5ca..5fc14ddbabd 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -33,7 +33,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 7d4d5d99446..cfc3c8e9a06 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -31,7 +31,7 @@ #include #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/port.h" @@ -52,15 +52,10 @@ using std::vector; namespace grpc { namespace testing { static std::string get_host(const std::string& worker) { - char* host; - char* port; - - gpr_split_host_port(worker.c_str(), &host, &port); - const string s(host); - - gpr_free(host); - gpr_free(port); - return s; + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(worker.c_str(), &host, &port); + return std::string(host.data(), host.size()); } static deque get_workers(const string& env_name) { @@ -324,11 +319,10 @@ std::unique_ptr RunScenario( client_config.add_server_targets(cli_target); } else { std::string host; - char* cli_target; + grpc_core::UniquePtr cli_target; host = get_host(workers[i]); - gpr_join_host_port(&cli_target, host.c_str(), init_status.port()); - client_config.add_server_targets(cli_target); - gpr_free(cli_target); + grpc_core::JoinHostPort(&cli_target, host.c_str(), init_status.port()); + client_config.add_server_targets(cli_target.get()); } } diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index 23fe72316a1..bdf94d86c10 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" @@ -279,12 +279,11 @@ QpsWorker::QpsWorker(int driver_port, int server_port, std::unique_ptr builder = CreateQpsServerBuilder(); if (driver_port >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", driver_port); + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", driver_port); builder->AddListeningPort( - server_address, + server_address.get(), GetCredentialsProvider()->GetServerCredentials(credential_type)); - gpr_free(server_address); } builder->RegisterService(impl_.get()); diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a5f8347c269..e9978212f95 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/completion_queue.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" @@ -80,11 +80,10 @@ class AsyncQpsServerTest final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } register_service(builder.get(), &async_service_); diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 4a346dd0178..1829905cb49 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -21,7 +21,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -103,11 +103,10 @@ class CallbackServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 2e63f5ec867..7b76e9c206a 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -25,7 +25,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -160,11 +160,10 @@ class SynchronousServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e2d753e02eb..d783dae496c 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1076,7 +1076,6 @@ src/core/lib/debug/trace.h \ src/core/lib/gpr/alloc.h \ src/core/lib/gpr/arena.h \ src/core/lib/gpr/env.h \ -src/core/lib/gpr/host_port.h \ src/core/lib/gpr/mpscq.h \ src/core/lib/gpr/murmur_hash.h \ src/core/lib/gpr/spinlock.h \ @@ -1098,6 +1097,7 @@ src/core/lib/gprpp/global_config.h \ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ +src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1107,6 +1107,7 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/http/format_request.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7768bca30f5..1dae91d2eaf 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1125,8 +1125,6 @@ src/core/lib/gpr/env.h \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ -src/core/lib/gpr/host_port.cc \ -src/core/lib/gpr/host_port.h \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -1175,6 +1173,8 @@ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ +src/core/lib/gprpp/host_port.cc \ +src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1184,6 +1184,7 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/gprpp/thd_posix.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 43fc3cc05ec..e894da1a9cb 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -683,7 +683,7 @@ "language": "c", "name": "gpr_host_port_test", "src": [ - "test/core/gpr/host_port_test.cc" + "test/core/gprpp/host_port_test.cc" ], "third_party": false, "type": "target" @@ -5058,6 +5058,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "string_view_test", + "src": [ + "test/core/gprpp/string_view_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8172,7 +8190,6 @@ "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -8199,6 +8216,7 @@ "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -8232,7 +8250,6 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8253,6 +8270,7 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8285,7 +8303,6 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8306,6 +8323,7 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8606,6 +8624,7 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", @@ -8763,6 +8782,7 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 5c24ec4fa15..77a751de162 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5730,6 +5730,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "string_view_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From ddde5f65beb4921344b64e958b7720b8c2c3ea29 Mon Sep 17 00:00:00 2001 From: yunjiaw26 <50971092+yunjiaw26@users.noreply.github.com> Date: Thu, 20 Jun 2019 21:21:04 -0700 Subject: [PATCH 429/676] Fix format error --- src/core/lib/iomgr/executor/mpmcqueue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 6deba05a421..7290c68db94 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -45,7 +45,7 @@ inline void* InfLenFIFOQueue::PopFront() { if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { gpr_timespec wait_time = - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); + gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); // Updates Stats info stats_.num_completed++; From 48cee18b2fc1475dc3ddd9ccb92d8bf9fcee58c5 Mon Sep 17 00:00:00 2001 From: yunjiaw26 <50971092+yunjiaw26@users.noreply.github.com> Date: Thu, 20 Jun 2019 21:21:48 -0700 Subject: [PATCH 430/676] Fix format error --- src/core/lib/iomgr/executor/mpmcqueue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index ae9a3b2826f..5970dba0c1d 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -119,11 +119,11 @@ class InfLenFIFOQueue : public MPMCQueueInterface { CondVar wait_nonempty_; // Wait on empty queue on get int num_waiters_; // Number of waiters - Node* queue_head_; // Head of the queue, remove position - Node* queue_tail_; // End of queue, insert position - Atomic count_{0}; // Number of elements in queue - Stats stats_; // Stats info - gpr_timespec busy_time; // Start time of busy queue + Node* queue_head_; // Head of the queue, remove position + Node* queue_tail_; // End of queue, insert position + Atomic count_{0}; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core From 857d8d14b0f8b3beed6e605026da528af4077781 Mon Sep 17 00:00:00 2001 From: yunjiaw26 <50971092+yunjiaw26@users.noreply.github.com> Date: Thu, 20 Jun 2019 21:22:56 -0700 Subject: [PATCH 431/676] Fix format error and memory leak --- test/core/iomgr/mpmcqueue_test.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 8f89b5c08bf..ad47c657def 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -42,9 +42,7 @@ class ProducerThread { public: ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, int num_items) - : start_index_(start_index), - num_items_(num_items), - queue_(queue) { + : start_index_(start_index), num_items_(num_items), queue_(queue) { items_ = nullptr; thd_ = grpc_core::Thread( "mpmcq_test_mt_put_thd", @@ -77,7 +75,6 @@ class ProducerThread { WorkItem** items_; }; - static void ConsumerThread(void* args) { grpc_core::InfLenFIFOQueue* queue = static_cast(args); @@ -104,13 +101,14 @@ static void test_get_empty(void) { // Fork threads. Threads should block at the beginning since queue is empty. for (int i = 0; i < num_threads; ++i) { - thds[i] = - grpc_core::Thread("mpmcq_test_ge_thd", ConsumerThread, &queue); + thds[i] = grpc_core::Thread("mpmcq_test_ge_thd", ConsumerThread, &queue); thds[i].Start(); } + WorkItem** items = new WorkItem*[THREAD_LARGE_ITERATION]; for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - queue.Put(static_cast(new WorkItem(i))); + items[i] = new WorkItem(i); + queue.Put(static_cast(items[i])); } gpr_log(GPR_DEBUG, "Terminating threads..."); @@ -120,6 +118,12 @@ static void test_get_empty(void) { for (int i = 0; i < num_threads; ++i) { thds[i].Join(); } + gpr_log(GPR_DEBUG, "Checking and Cleaning Up..."); + for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + GPR_ASSERT(items[i]->done); + delete items[i]; + } + delete[] items; gpr_log(GPR_DEBUG, "Done."); } @@ -148,14 +152,14 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "Fork ProducerThread..."); for (int i = 0; i < num_work_thd; ++i) { work_thds[i] = new ProducerThread(&queue, i * THREAD_LARGE_ITERATION, - THREAD_LARGE_ITERATION); + THREAD_LARGE_ITERATION); work_thds[i]->Start(); } gpr_log(GPR_DEBUG, "ProducerThread Started."); gpr_log(GPR_DEBUG, "Fork Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - get_thds[i] = grpc_core::Thread("mpmcq_test_mt_get_thd", ConsumerThread, - &queue); + get_thds[i] = + grpc_core::Thread("mpmcq_test_mt_get_thd", ConsumerThread, &queue); get_thds[i].Start(); } gpr_log(GPR_DEBUG, "Getter Thread Started."); From a16e89401225141ab118b304749b24790ba27c21 Mon Sep 17 00:00:00 2001 From: yunjiaw26 <50971092+yunjiaw26@users.noreply.github.com> Date: Thu, 20 Jun 2019 21:48:21 -0700 Subject: [PATCH 432/676] Fix format error :) --- src/core/lib/iomgr/executor/mpmcqueue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 5970dba0c1d..e5d2b6423ed 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -119,11 +119,11 @@ class InfLenFIFOQueue : public MPMCQueueInterface { CondVar wait_nonempty_; // Wait on empty queue on get int num_waiters_; // Number of waiters - Node* queue_head_; // Head of the queue, remove position - Node* queue_tail_; // End of queue, insert position - Atomic count_{0}; // Number of elements in queue - Stats stats_; // Stats info - gpr_timespec busy_time; // Start time of busy queue + Node* queue_head_; // Head of the queue, remove position + Node* queue_tail_; // End of queue, insert position + Atomic count_{0}; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core From 5435ac05ce7f7da170ad6ebb228b912b141e2730 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 21 Jun 2019 10:59:08 -0400 Subject: [PATCH 433/676] Fix obj-c tests. --- src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index fbcd4f888d4..ad426014a5b 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -82,7 +82,8 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr.get(), client_args, NULL); GPR_ASSERT(f->client != NULL); } @@ -95,7 +96,7 @@ static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, } f->server = grpc_server_create(server_args, NULL); grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); } From 152108e90791b5a1c5759bf21594463ce92a9ac1 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 09:25:01 -0700 Subject: [PATCH 434/676] Modify var type to match interface --- src/core/lib/iomgr/executor/mpmcqueue.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index e5d2b6423ed..7022cf492f2 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -119,11 +119,11 @@ class InfLenFIFOQueue : public MPMCQueueInterface { CondVar wait_nonempty_; // Wait on empty queue on get int num_waiters_; // Number of waiters - Node* queue_head_; // Head of the queue, remove position - Node* queue_tail_; // End of queue, insert position - Atomic count_{0}; // Number of elements in queue - Stats stats_; // Stats info - gpr_timespec busy_time; // Start time of busy queue + Node* queue_head_; // Head of the queue, remove position + Node* queue_tail_; // End of queue, insert position + Atomic count_{0}; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core From 2bf9234f147eeaf48b8c7e1b0a68c3d1556d1717 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 21 Jun 2019 13:36:06 -0400 Subject: [PATCH 435/676] building upb as part of cmake build is not necessary --- CMakeLists.txt | 52 ------------------------------- templates/CMakeLists.txt.template | 2 +- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76f19024f0b..b449e353a9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5766,58 +5766,6 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) -add_library(upb - third_party/upb/google/protobuf/descriptor.upb.c - third_party/upb/upb/decode.c - third_party/upb/upb/def.c - third_party/upb/upb/encode.c - third_party/upb/upb/handlers.c - third_party/upb/upb/msg.c - third_party/upb/upb/msgfactory.c - third_party/upb/upb/sink.c - third_party/upb/upb/table.c - third_party/upb/upb/upb.c -) - -if(WIN32 AND MSVC) - set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(upb - PUBLIC $ $ - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(upb PROPERTIES LINKER_LANGUAGE C) - # only use the flags for C++ source files - target_compile_options(upb PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() -target_link_libraries(upb - ${_gRPC_SSL_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} -) - - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_library(bad_client_test test/core/bad_client/bad_client.cc ) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 43bc063aee5..d42d2c6d0c8 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -325,7 +325,7 @@ % for lib in libs: % if lib.build in ["all", "protoc", "tool", "test", "private"] and not lib.boringssl: % if not lib.get('build_system', []) or 'cmake' in lib.get('build_system', []): - % if not lib.name in ['ares', 'benchmark', 'z']: # we build these using CMake instead + % if not lib.name in ['ares', 'benchmark', 'upb', 'z']: # we build these using CMake instead % if lib.build in ["test", "private"]: if (gRPC_BUILD_TESTS) ${cc_library(lib)} From 3ce20819cfd0919ccabdff08166bdb182fdadd41 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 21 Jun 2019 10:51:57 -0700 Subject: [PATCH 436/676] Modify codegen to use grpc_impl namespace and other cleanups --- .../impl/codegen/async_generic_service.h | 4 +- include/grpcpp/impl/codegen/async_stream.h | 32 +++++------ .../grpcpp/impl/codegen/async_unary_call.h | 16 +++--- include/grpcpp/impl/codegen/call_op_set.h | 8 +-- include/grpcpp/impl/codegen/client_callback.h | 36 ++++++------- .../grpcpp/impl/codegen/intercepted_channel.h | 2 +- .../grpcpp/impl/codegen/method_handler_impl.h | 33 ++++++------ .../grpcpp/impl/codegen/server_interface.h | 2 +- include/grpcpp/impl/codegen/sync_stream.h | 53 ++++++++++--------- include/grpcpp/impl/server_builder_plugin.h | 4 +- include/grpcpp/security/credentials.h | 1 + include/grpcpp/security/credentials_impl.h | 28 +++++----- include/grpcpp/server_impl.h | 28 +++++----- src/compiler/cpp_generator.cc | 5 +- src/cpp/client/create_channel_internal.h | 1 + src/cpp/client/insecure_credentials.cc | 10 ++-- src/cpp/client/secure_credentials.cc | 10 ++-- src/cpp/client/secure_credentials.h | 8 +-- test/cpp/qps/server.h | 1 + test/cpp/util/create_test_channel.h | 22 ++++---- 20 files changed, 157 insertions(+), 147 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 46d09121a7b..d8e6f49b2f3 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -33,7 +33,7 @@ typedef ServerAsyncResponseWriter GenericServerAsyncResponseWriter; typedef ServerAsyncReader GenericServerAsyncReader; typedef ServerAsyncWriter GenericServerAsyncWriter; -class GenericServerContext final : public ServerContext { +class GenericServerContext final : public ::grpc_impl::ServerContext { public: const grpc::string& method() const { return method_; } const grpc::string& host() const { return host_; } @@ -99,7 +99,7 @@ class ServerGenericBidiReactor virtual void OnStarted(GenericServerContext* context) {} private: - void OnStarted(ServerContext* ctx) final { + void OnStarted(::grpc_impl::ServerContext* ctx) final { OnStarted(static_cast(ctx)); } }; diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index f95772650a2..f762833b3b1 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -181,7 +181,7 @@ class ClientAsyncReaderFactory { static ClientAsyncReader* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request, + ::grpc_impl::ClientContext* context, const W& request, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -260,7 +260,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { private: friend class internal::ClientAsyncReaderFactory; template - ClientAsyncReader(::grpc::internal::Call call, ClientContext* context, + ClientAsyncReader(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, const W& request, bool start, void* tag) : context_(context), call_(call), started_(start) { // TODO(ctiller): don't assert @@ -280,7 +280,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { call_.PerformOps(&init_ops_); } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, @@ -329,7 +329,7 @@ class ClientAsyncWriterFactory { static ClientAsyncWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response, + ::grpc_impl::ClientContext* context, R* response, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -426,7 +426,7 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { private: friend class internal::ClientAsyncWriterFactory; template - ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context, + ClientAsyncWriter(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, R* response, bool start, void* tag) : context_(context), call_(call), started_(start) { finish_ops_.RecvMessage(response); @@ -449,7 +449,7 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> @@ -493,7 +493,7 @@ class ClientAsyncReaderWriterFactory { /// used to send to the server when starting the call. static ClientAsyncReaderWriter* Create( ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, + const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); @@ -599,7 +599,7 @@ class ClientAsyncReaderWriter final private: friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context, + ClientAsyncReaderWriter(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, bool start, void* tag) : context_(context), call_(call), started_(start) { if (start) { @@ -620,7 +620,7 @@ class ClientAsyncReaderWriter final } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> @@ -696,7 +696,7 @@ class ServerAsyncReaderInterface template class ServerAsyncReader final : public ServerAsyncReaderInterface { public: - explicit ServerAsyncReader(ServerContext* ctx) + explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -782,7 +782,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { void BindCall(::grpc::internal::Call* call) override { call_ = *call; } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; @@ -843,7 +843,7 @@ class ServerAsyncWriterInterface template class ServerAsyncWriter final : public ServerAsyncWriterInterface { public: - explicit ServerAsyncWriter(ServerContext* ctx) + explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -940,7 +940,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, @@ -1009,7 +1009,7 @@ template class ServerAsyncReaderWriter final : public ServerAsyncReaderWriterInterface { public: - explicit ServerAsyncReaderWriter(ServerContext* ctx) + explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -1114,7 +1114,7 @@ class ServerAsyncReaderWriter final } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_ops_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 4b97cf29018..4c0f4339c8f 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -80,8 +80,8 @@ class ClientAsyncResponseReaderFactory { /// used to send to the server when starting the call. template static ClientAsyncResponseReader* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, + ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, const W& request, bool start) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -156,13 +156,13 @@ class ClientAsyncResponseReader final private: friend class internal::ClientAsyncResponseReaderFactory; - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; ::grpc::internal::Call call_; bool started_; bool initial_metadata_read_ = false; template - ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context, + ClientAsyncResponseReader(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, const W& request, bool start) : context_(context), call_(call), started_(start) { // Bind the metadata at time of StartCallInternal but set up the rest here @@ -199,7 +199,7 @@ template class ServerAsyncResponseWriter final : public internal::ServerAsyncStreamingInterface { public: - explicit ServerAsyncResponseWriter(ServerContext* ctx) + explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. @@ -289,7 +289,7 @@ class ServerAsyncResponseWriter final void BindCall(::grpc::internal::Call* call) override { call_ = *call; } ::grpc::internal::Call call_; - ServerContext* ctx_; + ::grpc_impl::ServerContext* ctx_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> meta_buf_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index c3ae6c4e3d2..d0958bbb251 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -697,7 +697,7 @@ class CallOpRecvInitialMetadata { public: CallOpRecvInitialMetadata() : metadata_map_(nullptr) {} - void RecvInitialMetadata(ClientContext* context) { + void RecvInitialMetadata(::grpc_impl::ClientContext* context) { context->initial_metadata_received_ = true; metadata_map_ = &context->recv_initial_metadata_; } @@ -746,7 +746,7 @@ class CallOpClientRecvStatus { CallOpClientRecvStatus() : recv_status_(nullptr), debug_error_string_(nullptr) {} - void ClientRecvStatus(ClientContext* context, Status* status) { + void ClientRecvStatus(::grpc_impl::ClientContext* context, Status* status) { client_context_ = context; metadata_map_ = &client_context_->trailing_metadata_; recv_status_ = status; @@ -807,7 +807,7 @@ class CallOpClientRecvStatus { private: bool hijacked_ = false; - ClientContext* client_context_; + ::grpc_impl::ClientContext* client_context_; MetadataMap* metadata_map_; Status* recv_status_; const char* debug_error_string_; diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 86d06b72c91..9441a48b051 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -44,8 +44,8 @@ class RpcMethod; /// TODO(vjpai): Combine as much as possible with the blocking unary call code template void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CallbackUnaryCallImpl x( channel, method, context, request, result, on_completion); @@ -55,8 +55,8 @@ template class CallbackUnaryCallImpl { public: CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CompletionQueue* cq = channel->CallbackCQ(); GPR_CODEGEN_ASSERT(cq != nullptr); @@ -550,7 +550,7 @@ class ClientCallbackReaderWriterImpl friend class ClientCallbackReaderWriterFactory; ClientCallbackReaderWriterImpl( - Call call, ClientContext* context, + Call call, ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) : context_(context), call_(call), @@ -559,7 +559,7 @@ class ClientCallbackReaderWriterImpl this->BindReactor(reactor); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientBidiReactor* const reactor_; @@ -594,7 +594,7 @@ class ClientCallbackReaderWriterFactory { public: static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -692,7 +692,7 @@ class ClientCallbackReaderImpl template ClientCallbackReaderImpl( - Call call, ClientContext* context, Request* request, + Call call, ::grpc_impl::ClientContext* context, Request* request, ::grpc::experimental::ClientReadReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -701,7 +701,7 @@ class ClientCallbackReaderImpl start_ops_.ClientSendClose(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientReadReactor* const reactor_; @@ -729,7 +729,7 @@ class ClientCallbackReaderFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, + ::grpc_impl::ClientContext* context, const Request* request, ::grpc::experimental::ClientReadReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -866,7 +866,7 @@ class ClientCallbackWriterImpl template ClientCallbackWriterImpl( - Call call, ClientContext* context, Response* response, + Call call, ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) : context_(context), call_(call), @@ -877,7 +877,7 @@ class ClientCallbackWriterImpl finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientWriteReactor* const reactor_; @@ -909,7 +909,7 @@ class ClientCallbackWriterFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, Response* response, + ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -976,8 +976,8 @@ class ClientCallbackUnaryImpl final friend class ClientCallbackUnaryFactory; template - ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request, - Response* response, + ClientCallbackUnaryImpl(Call call, ::grpc_impl::ClientContext* context, + Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -988,7 +988,7 @@ class ClientCallbackUnaryImpl final finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientUnaryReactor* const reactor_; @@ -1011,8 +1011,8 @@ class ClientCallbackUnaryFactory { template static void Create(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, - Response* response, + ::grpc_impl::ClientContext* context, + const Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index cd0fcc06753..bcdd89db741 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -49,7 +49,7 @@ class InterceptedChannel : public ChannelInterface { InterceptedChannel(ChannelInterface* channel, size_t pos) : channel_(channel), interceptor_pos_(pos) {} - Call CreateCall(const RpcMethod& method, ClientContext* context, + Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index dee1cb56ad1..95b804c50e8 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -52,7 +52,8 @@ Status CatchingFunctionHandler(Callable&& handler) { template class RpcMethodHandler : public MethodHandler { public: - RpcMethodHandler(std::function func, ServiceType* service) @@ -103,8 +104,8 @@ class RpcMethodHandler : public MethodHandler { private: /// Application provided rpc handler function. - std::function + std::function func_; // The class the above handler function lives in. ServiceType* service_; @@ -115,7 +116,7 @@ template class ClientStreamingHandler : public MethodHandler { public: ClientStreamingHandler( - std::function*, ResponseType*)> func, ServiceType* service) @@ -147,8 +148,8 @@ class ClientStreamingHandler : public MethodHandler { } private: - std::function*, - ResponseType*)> + std::function*, ResponseType*)> func_; ServiceType* service_; }; @@ -158,8 +159,8 @@ template class ServerStreamingHandler : public MethodHandler { public: ServerStreamingHandler( - std::function*)> + std::function*)> func, ServiceType* service) : func_(func), service_(service) {} @@ -207,8 +208,8 @@ class ServerStreamingHandler : public MethodHandler { } private: - std::function*)> + std::function*)> func_; ServiceType* service_; }; @@ -224,7 +225,7 @@ template class TemplatedBidiStreamingHandler : public MethodHandler { public: TemplatedBidiStreamingHandler( - std::function func) + std::function func) : func_(func), write_needed_(WriteNeeded) {} void RunHandler(const HandlerParameter& param) final { @@ -256,7 +257,7 @@ class TemplatedBidiStreamingHandler : public MethodHandler { } private: - std::function func_; + std::function func_; const bool write_needed_; }; @@ -266,7 +267,7 @@ class BidiStreamingHandler ServerReaderWriter, false> { public: BidiStreamingHandler( - std::function*)> func, ServiceType* service) @@ -281,7 +282,7 @@ class StreamedUnaryHandler ServerUnaryStreamer, true> { public: explicit StreamedUnaryHandler( - std::function*)> func) : TemplatedBidiStreamingHandler< @@ -294,7 +295,7 @@ class SplitServerStreamingHandler ServerSplitStreamer, false> { public: explicit SplitServerStreamingHandler( - std::function*)> func) : TemplatedBidiStreamingHandler< @@ -307,7 +308,7 @@ template class ErrorMethodHandler : public MethodHandler { public: template - static void FillOps(ServerContext* context, T* ops) { + static void FillOps(::grpc_impl::ServerContext* context, T* ops) { Status status(code, ""); if (!context->sent_initial_metadata_) { ops->SendInitialMetadata(&context->initial_metadata_, diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 9600e5f053d..6239b4c2d4d 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace grpc_impl { diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 0d3fdfcb8dc..cdff2f487dc 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -21,10 +21,10 @@ #include #include -#include +#include #include #include -#include +#include #include #include @@ -120,7 +120,7 @@ class WriterInterface { /// /// \param msg The message to be written to the stream. /// - /// \return \a true on success, \a false when the stream has been closed. + /// \return \a true on success, \a false when the stream has been closed.access/marconi/common/grpc/async_grpc_container.h inline bool Write(const W& msg) { return Write(msg, WriteOptions()); } /// Write \a msg and coalesce it with the writing of trailing metadata, using @@ -142,7 +142,7 @@ class WriterInterface { } }; -} // namespace internal +} // namespace internalaccess/marconi/common/grpc/async_grpc_container.h /// Client-side interface for streaming reads of message of type \a R. template @@ -163,7 +163,8 @@ class ClientReaderFactory { template static ClientReader* Create(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request) { + ::grpc_impl::ClientContext* context, + const W& request) { return new ClientReader(channel, method, context, request); } }; @@ -230,8 +231,8 @@ class ClientReader final : public ClientReaderInterface { private: friend class internal::ClientReaderFactory; - ClientContext* context_; - CompletionQueue cq_; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; /// Block to create a stream and write the initial metadata and \a request @@ -240,7 +241,7 @@ class ClientReader final : public ClientReaderInterface { template ClientReader(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request) + ::grpc_impl::ClientContext* context, const W& request) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -281,7 +282,8 @@ class ClientWriterFactory { template static ClientWriter* Create(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response) { + ::grpc_impl::ClientContext* context, + R* response) { return new ClientWriter(channel, method, context, response); } }; @@ -374,7 +376,7 @@ class ClientWriter : public ClientWriterInterface { template ClientWriter(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response) + ::grpc_impl::ClientContext* context, R* response) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -393,12 +395,12 @@ class ClientWriter : public ClientWriterInterface { } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, ::grpc::internal::CallOpGenericRecvMessage, ::grpc::internal::CallOpClientRecvStatus> finish_ops_; - CompletionQueue cq_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; }; @@ -431,7 +433,8 @@ class ClientReaderWriterFactory { public: static ClientReaderWriter* Create( ::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, ClientContext* context) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) { return new ClientReaderWriter(channel, method, context); } }; @@ -539,8 +542,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { private: friend class internal::ClientReaderWriterFactory; - ClientContext* context_; - CompletionQueue cq_; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; ::grpc::internal::Call call_; /// Block to create a stream and write the initial metadata and \a request @@ -548,7 +551,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { /// used to send to the server when starting the call. ClientReaderWriter(::grpc::ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context) + ::grpc_impl::ClientContext* context) : context_(context), cq_(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, @@ -607,12 +610,12 @@ class ServerReader final : public ServerReaderInterface { private: internal::Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; template friend class internal::ClientStreamingHandler; - ServerReader(internal::Call* call, ServerContext* ctx) + ServerReader(internal::Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} }; @@ -681,12 +684,12 @@ class ServerWriter final : public ServerWriterInterface { private: internal::Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; template friend class internal::ServerStreamingHandler; - ServerWriter(internal::Call* call, ServerContext* ctx) + ServerWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} }; @@ -701,7 +704,7 @@ namespace internal { template class ServerReaderWriterBody final { public: - ServerReaderWriterBody(Call* call, ServerContext* ctx) + ServerReaderWriterBody(Call* call, ::grpc_impl::ServerContext* ctx) : call_(call), ctx_(ctx) {} void SendInitialMetadata() { @@ -759,7 +762,7 @@ class ServerReaderWriterBody final { private: Call* const call_; - ServerContext* const ctx_; + ::grpc_impl::ServerContext* const ctx_; }; } // namespace internal @@ -797,7 +800,7 @@ class ServerReaderWriter final : public ServerReaderWriterInterface { friend class internal::TemplatedBidiStreamingHandler, false>; - ServerReaderWriter(internal::Call* call, ServerContext* ctx) + ServerReaderWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx) {} }; @@ -865,7 +868,7 @@ class ServerUnaryStreamer final friend class internal::TemplatedBidiStreamingHandler< ServerUnaryStreamer, true>; - ServerUnaryStreamer(internal::Call* call, ServerContext* ctx) + ServerUnaryStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx), read_done_(false), write_done_(false) {} }; @@ -925,7 +928,7 @@ class ServerSplitStreamer final friend class internal::TemplatedBidiStreamingHandler< ServerSplitStreamer, false>; - ServerSplitStreamer(internal::Call* call, ServerContext* ctx) + ServerSplitStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) : body_(call, ctx), read_done_(false) {} }; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 84a88f2dd7b..349995c8c1c 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -21,11 +21,11 @@ #include +#include #include namespace grpc_impl { -class ChannelArguments; class ServerBuilder; class ServerInitializer; } // namespace grpc_impl @@ -57,7 +57,7 @@ class ServerBuilderPlugin { /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), /// before the Server instance is created. - virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {} + virtual void UpdateChannelArguments(ChannelArguments* args) {} virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index e924275d592..b124d3d37be 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -28,6 +28,7 @@ typedef ::grpc_impl::CallCredentials CallCredentials; typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; +typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; static inline std::shared_ptr GoogleDefaultCredentials() { diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 29ba2075c29..34920a55bbe 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -24,11 +24,11 @@ #include #include -#include +#include #include #include #include -#include +#include #include #include @@ -41,16 +41,16 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const ChannelArguments& args); namespace experimental { -std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); @@ -75,27 +75,27 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( + friend std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const ChannelArguments& args); - friend std::shared_ptr<::grpc::Channel> + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ChannelArguments& args, std::vector> interceptor_creators); - virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) = 0; + virtual std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + virtual std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) { diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index b75012e5da8..a5c8670913e 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -27,16 +27,16 @@ #include #include -#include -#include +#include #include #include #include +#include #include #include #include #include -#include +#include #include #include @@ -80,7 +80,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { public: virtual ~GlobalCallbacks() {} /// Called before server is created. - virtual void UpdateArguments(grpc::ChannelArguments* args) {} + virtual void UpdateArguments(ChannelArguments* args) {} /// Called before application callback for each synchronous server request virtual void PreSynchronousRequest(grpc_impl::ServerContext* context) = 0; /// Called after application callback for each synchronous server request @@ -108,8 +108,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { } /// Establish a channel for in-process communication - std::shared_ptr<::grpc::Channel> InProcessChannel( - const grpc::ChannelArguments& args); + std::shared_ptr InProcessChannel(const ChannelArguments& args); /// NOTE: class experimental_type is not part of the public API of this class. /// TODO(yashykt): Integrate into public API when this is no longer @@ -120,8 +119,8 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// Establish a channel for in-process communication with client /// interceptors - std::shared_ptr<::grpc::Channel> InProcessChannelWithInterceptors( - const grpc::ChannelArguments& args, + std::shared_ptr InProcessChannelWithInterceptors( + const ChannelArguments& args, std::vector> interceptor_creators); @@ -182,9 +181,8 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on /// server completion queues passed via sync_server_cqs param. - Server( - int max_message_size, grpc::ChannelArguments* args, - std::shared_ptr>> + Server(int max_message_size, ChannelArguments* args, + std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, std::vector< @@ -202,7 +200,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// caller is required to keep all completion queues live until the server is /// destroyed. /// \param num_cqs How many completion queues does \a cqs hold. - void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override; + void Start(ServerCompletionQueue** cqs, size_t num_cqs) override; grpc_server* server() override { return server_; } @@ -283,7 +281,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { return max_receive_message_size_; } - grpc::CompletionQueue* CallbackCQ() override; + CompletionQueue* CallbackCQ() override; grpc_impl::ServerInitializer* initializer(); @@ -304,7 +302,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// The following completion queues are ONLY used in case of Sync API /// i.e. if the server has any services with sync methods. The server uses /// these completion queues to poll for new RPCs - std::shared_ptr>> + std::shared_ptr>> sync_server_cqs_; /// List of \a ThreadManager instances (one for each cq in @@ -374,7 +372,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { // It is _not owned_ by the server; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). // It is protected by mu_ - grpc::CompletionQueue* callback_cq_ = nullptr; + CompletionQueue* callback_cq_ = nullptr; }; } // namespace grpc_impl diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 23e3bd50eff..358efe9fd79 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -142,14 +142,17 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/client_callback.h", + "grpcpp/impl/codegen/client_context.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", "grpcpp/impl/codegen/server_callback.h", + "grpcpp/impl/codegen/server_context.h", "grpcpp/impl/codegen/service_type.h", "grpcpp/impl/codegen/status.h", "grpcpp/impl/codegen/stub_options.h", - "grpcpp/impl/codegen/sync_stream.h"}; + "grpcpp/impl/codegen/sync_stream.h", + }; std::vector headers(headers_strs, array_end(headers_strs)); PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 3b201afb5a7..4abd4c3dda9 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -21,6 +21,7 @@ #include +#include #include #include diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index dcbb56dccda..0d4ac9978f2 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -16,8 +16,6 @@ * */ -#include - #include #include #include @@ -31,16 +29,16 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) override { + std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, std::vector>()); } - std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) override { diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 197112d4bb7..d73b3e035c8 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -36,17 +36,17 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) { +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, std::vector>()); } -std::shared_ptr +std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators) { @@ -209,7 +209,7 @@ std::shared_ptr CompositeCallCredentials( return nullptr; } -std::shared_ptr MetadataCredentialsFromPlugin( +std::shared_ptr MetadataCredentialsFromPlugin( std::unique_ptr plugin) { grpc::GrpcLibraryCodegen init; // To call grpc_init(). const char* type = plugin->GetType(); diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index c4eef6c746d..dd379ca657d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -39,14 +39,14 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr<::grpc::Channel> CreateChannelImpl( - const grpc::string& target, const grpc::ChannelArguments& args) override; + std::shared_ptr CreateChannelImpl( + const grpc::string& target, const ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( - const grpc::string& target, const grpc::ChannelArguments& args, + std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, std::vector> interceptor_creators) override; diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 89b0e3af4b2..6c2f36451bc 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -19,6 +19,7 @@ #ifndef TEST_QPS_SERVER_H #define TEST_QPS_SERVER_H +#include #include #include #include diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index 42564a31ec8..131e8264114 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -21,8 +21,11 @@ #include +#include #include #include +#include + namespace grpc_impl { @@ -32,36 +35,35 @@ class Channel; namespace grpc { namespace testing { - typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); @@ -76,7 +78,8 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr& creds, const ChannelArguments& args, + const std::shared_ptr& creds, + const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); @@ -84,7 +87,8 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, - const std::shared_ptr& creds, const ChannelArguments& args, + const std::shared_ptr& creds, + const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); From 3ddff567b7cae91d1b313d3ea7f6defb865c75a1 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Fri, 21 Jun 2019 10:55:26 -0700 Subject: [PATCH 437/676] Fix the missing traces of metadata unref. --- src/core/lib/transport/metadata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 3cef031031d..4b9685066e5 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -348,10 +348,11 @@ inline void grpc_mdelem_unref(grpc_mdelem gmd) { free an interned md at any time: it's unsafe from this point on to access it so we read the hash now. */ uint32_t hash = md->hash(); - if (GPR_UNLIKELY(md->Unref())) { #ifndef NDEBUG + if (GPR_UNLIKELY(md->Unref(file, line))) { grpc_mdelem_on_final_unref(storage, md, hash, file, line); #else + if (GPR_UNLIKELY(md->Unref())) { grpc_mdelem_on_final_unref(storage, md, hash); #endif } From 63083d44725546e2f020e783ae5bdb26fd6d8afc Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 21 Jun 2019 11:19:34 -0700 Subject: [PATCH 438/676] Code cleanup --- include/grpcpp/generic/generic_stub_impl.h | 1 + src/cpp/client/insecure_credentials.cc | 2 +- test/cpp/util/create_test_channel.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index 90414611cbd..fdbc0d0a272 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -21,6 +21,7 @@ #include +#include #include #include #include diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 0d4ac9978f2..0556fa0e50f 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -15,11 +15,11 @@ * limitations under the License. * */ +#include #include #include #include -#include #include #include #include "src/cpp/client/create_channel_internal.h" diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index 131e8264114..ab5c7f39ebb 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -35,6 +35,7 @@ class Channel; namespace grpc { namespace testing { + typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing From 491d4a8d935115dbd4e3073776ee7f665ebca4f4 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 11:31:46 -0700 Subject: [PATCH 439/676] test name matching --- test/core/iomgr/mpmcqueue_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index ad47c657def..fdcc2d6019f 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -128,7 +128,7 @@ static void test_get_empty(void) { } static void test_FIFO(void) { - gpr_log(GPR_INFO, "test_large_queue"); + gpr_log(GPR_INFO, "test_FIFO"); grpc_core::InfLenFIFOQueue large_queue; for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { large_queue.Put(static_cast(new WorkItem(i))); From fbd5957ee83c1dcc3c59b0c8707cc2b8061efbbe Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 21 Jun 2019 12:28:55 -0700 Subject: [PATCH 440/676] Sanity and build fixes --- include/grpcpp/impl/codegen/async_stream.h | 27 ++++++++++--------- .../grpcpp/impl/codegen/async_unary_call.h | 7 ++--- .../grpcpp/impl/codegen/method_handler_impl.h | 6 ++--- include/grpcpp/impl/codegen/sync_stream.h | 4 +-- include/grpcpp/server_impl.h | 20 +++++++------- test/cpp/codegen/compiler_test_golden | 2 ++ test/cpp/qps/server.h | 2 +- test/cpp/util/create_test_channel.h | 7 ++--- 8 files changed, 39 insertions(+), 36 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index f762833b3b1..417dceb587f 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -181,8 +181,8 @@ class ClientAsyncReaderFactory { static ClientAsyncReader* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const W& request, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + const W& request, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncReader))) @@ -260,8 +260,9 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { private: friend class internal::ClientAsyncReaderFactory; template - ClientAsyncReader(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, - const W& request, bool start, void* tag) + ClientAsyncReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, + bool start, void* tag) : context_(context), call_(call), started_(start) { // TODO(ctiller): don't assert GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); @@ -329,8 +330,8 @@ class ClientAsyncWriterFactory { static ClientAsyncWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, R* response, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + R* response, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncWriter))) @@ -426,8 +427,9 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { private: friend class internal::ClientAsyncWriterFactory; template - ClientAsyncWriter(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, - R* response, bool start, void* tag) + ClientAsyncWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, R* response, + bool start, void* tag) : context_(context), call_(call), started_(start) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); @@ -493,8 +495,8 @@ class ClientAsyncReaderWriterFactory { /// used to send to the server when starting the call. static ClientAsyncReaderWriter* Create( ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, - bool start, void* tag) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -599,8 +601,9 @@ class ClientAsyncReaderWriter final private: friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, - bool start, void* tag) + ClientAsyncReaderWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, bool start, + void* tag) : context_(context), call_(call), started_(start) { if (start) { StartCallInternal(tag); diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 4c0f4339c8f..5da6a649f14 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -81,8 +81,8 @@ class ClientAsyncResponseReaderFactory { template static ClientAsyncResponseReader* Create( ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, - const W& request, bool start) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request, bool start) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncResponseReader))) @@ -162,7 +162,8 @@ class ClientAsyncResponseReader final bool initial_metadata_read_ = false; template - ClientAsyncResponseReader(::grpc::internal::Call call, ::grpc_impl::ClientContext* context, + ClientAsyncResponseReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, bool start) : context_(context), call_(call), started_(start) { // Bind the metadata at time of StartCallInternal but set up the rest here diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index 95b804c50e8..1903f898ba8 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -54,9 +54,9 @@ class RpcMethodHandler : public MethodHandler { public: RpcMethodHandler( std::function - func, - ServiceType* service) + const RequestType*, ResponseType*)> + func, + ServiceType* service) : func_(func), service_(service) {} void RunHandler(const HandlerParameter& param) final { diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index cdff2f487dc..9d030a13a71 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -120,7 +120,7 @@ class WriterInterface { /// /// \param msg The message to be written to the stream. /// - /// \return \a true on success, \a false when the stream has been closed.access/marconi/common/grpc/async_grpc_container.h + /// \return \a true on success, \a false when the stream has been closed. inline bool Write(const W& msg) { return Write(msg, WriteOptions()); } /// Write \a msg and coalesce it with the writing of trailing metadata, using @@ -142,7 +142,7 @@ class WriterInterface { } }; -} // namespace internalaccess/marconi/common/grpc/async_grpc_container.h +} // namespace internal /// Client-side interface for streaming reads of message of type \a R. template diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index a5c8670913e..056f5f0c5ab 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -183,16 +183,16 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { /// server completion queues passed via sync_server_cqs param. Server(int max_message_size, ChannelArguments* args, std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - std::vector< - std::shared_ptr> - acceptors, - grpc_resource_quota* server_rq = nullptr, - std::vector> - interceptor_creators = std::vector>()); + sync_server_cqs, + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + std::vector< + std::shared_ptr> + acceptors, + grpc_resource_quota* server_rq = nullptr, + std::vector> + interceptor_creators = std::vector>()); /// Start the server. /// diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 64ab123123b..035955023b8 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -31,10 +31,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 6c2f36451bc..2b82abce202 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -19,9 +19,9 @@ #ifndef TEST_QPS_SERVER_H #define TEST_QPS_SERVER_H -#include #include #include +#include #include #include #include diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index ab5c7f39ebb..2aacbc9bdf3 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -26,7 +26,6 @@ #include #include - namespace grpc_impl { class Channel; @@ -79,8 +78,7 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); @@ -88,8 +86,7 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); From 889224227c0724dbff8bcfa79ce02c235e56612d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 21 Jun 2019 15:48:17 -0400 Subject: [PATCH 441/676] Fix a typo. --- src/core/lib/gprpp/host_port.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/host_port.h b/src/core/lib/gprpp/host_port.h index 16f1c807580..9a0b492b98f 100644 --- a/src/core/lib/gprpp/host_port.h +++ b/src/core/lib/gprpp/host_port.h @@ -41,7 +41,7 @@ int JoinHostPort(UniquePtr* out, const char* host, int port); and port number. There are two variants of this method: - 1) StringView ouptut: port and host are returned as views on name. + 1) StringView output: port and host are returned as views on name. 2) char* output: port and host are copied into newly allocated strings. Prefer variant (1) over (2), because no allocation or copy is performed in From 624839b7043e8ac3463765152e1d9326d474c691 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 20 Jun 2019 10:32:54 -0700 Subject: [PATCH 442/676] Add example Python server using compression. --- examples/python/compression/BUILD.bazel | 44 +++++++ examples/python/compression/README.md | 58 ++++++++++ examples/python/compression/client.py | 76 ++++++++++++ examples/python/compression/server.py | 109 ++++++++++++++++++ .../test/compression_example_test.py | 62 ++++++++++ 5 files changed, 349 insertions(+) create mode 100644 examples/python/compression/BUILD.bazel create mode 100644 examples/python/compression/README.md create mode 100644 examples/python/compression/client.py create mode 100644 examples/python/compression/server.py create mode 100644 examples/python/compression/test/compression_example_test.py diff --git a/examples/python/compression/BUILD.bazel b/examples/python/compression/BUILD.bazel new file mode 100644 index 00000000000..b95d7cccc77 --- /dev/null +++ b/examples/python/compression/BUILD.bazel @@ -0,0 +1,44 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +py_binary( + name = "server", + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], + srcs_version = "PY2AND3", +) + +py_binary( + name = "client", + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], + srcs_version = "PY2AND3", +) + +py_test( + name = "test/compression_example_test", + srcs = ["test/compression_example_test.py"], + srcs_version = "PY2AND3", + data = [ + ":client", + ":server", + ], + size = "small", +) diff --git a/examples/python/compression/README.md b/examples/python/compression/README.md new file mode 100644 index 00000000000..c719bba07f8 --- /dev/null +++ b/examples/python/compression/README.md @@ -0,0 +1,58 @@ +## Compression with gRPC Python + +gRPC offers lossless compression options in order to decrease the number of bits +transferred over the wire. Three levels of compression are available: + + - `grpc.Compression.NoCompression` - No compression is applied to the payload. (default) + - `grpc.Compression.Deflate` - The "Deflate" algorithm is applied to the payload. + - `grpc.Compression.Gzip` - The Gzip algorithm is applied to the payload. + +The default option on both clients and servers is `grpc.Compression.NoCompression`. + +See [the gRPC Compression Spec](https://github.com/grpc/grpc/blob/master/doc/compression.md) +for more information. + +### Client Side Compression + +Compression may be set at two levels on the client side. + +#### At the channel level + +```python +with grpc.insecure_channel('foo.bar:1234', compression=grpc.Compression.Gzip) as channel: + use_channel(channel) +``` + +#### At the call level + +Setting the compression method at the call level will override any settings on +the channel level. + +```python +stub = helloworld_pb2_grpc.GreeterStub(channel) +response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), + compression=grpc.Compression.Deflate) +``` + + +### Server Side Compression + +Additionally, compression may be set at two levels on the server side. + +#### On the entire server + +```python +server = grpc.server(futures.ThreadPoolExecutor(), + compression=grpc.Compression.Gzip) +``` + +#### For an individual RPC + +```python +def SayHello(self, request, context): + context.set_response_compression(grpc.Compression.NoCompression) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) +``` + +Setting the compression method for an individual RPC will override any setting +supplied at server creation time. diff --git a/examples/python/compression/client.py b/examples/python/compression/client.py new file mode 100644 index 00000000000..444f14c1f68 --- /dev/null +++ b/examples/python/compression/client.py @@ -0,0 +1,76 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""An example of compression on the client side with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import logging +import grpc + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_DESCRIPTION = 'A client capable of compression.' +_COMPRESSION_OPTIONS = { + "none": grpc.Compression.NoCompression, + "deflate": grpc.Compression.Deflate, + "gzip": grpc.Compression.Gzip, +} + +_LOGGER = logging.getLogger(__name__) + + +def run_client(channel_compression, call_compression, target): + with grpc.insecure_channel( + target, compression=channel_compression) as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), + compression=call_compression, + wait_for_ready=True) + print("Response: {}".format(response)) + + +def main(): + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument( + '--channel_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The compression method to use for the channel.') + parser.add_argument( + '--call_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The compression method to use for an individual call.') + parser.add_argument( + '--server', + default='localhost:50051', + type=str, + nargs='?', + help='The host-port pair at which to reach the server.') + args = parser.parse_args() + channel_compression = _COMPRESSION_OPTIONS[args.channel_compression] + call_compression = _COMPRESSION_OPTIONS[args.call_compression] + run_client(channel_compression, call_compression, args.server) + + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/examples/python/compression/server.py b/examples/python/compression/server.py new file mode 100644 index 00000000000..bc13e60cb5b --- /dev/null +++ b/examples/python/compression/server.py @@ -0,0 +1,109 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""An example of compression on the server side with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from concurrent import futures +import argparse +import logging +import threading +import time +import grpc + +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc + +_DESCRIPTION = 'A server capable of compression.' +_COMPRESSION_OPTIONS = { + "none": grpc.Compression.NoCompression, + "deflate": grpc.Compression.Deflate, + "gzip": grpc.Compression.Gzip, +} +_LOGGER = logging.getLogger(__name__) + +_SERVER_HOST = 'localhost' +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self, no_compress_every_n): + super(Greeter, self).__init__() + self._no_compress_every_n = 0 + self._request_counter = 0 + self._counter_lock = threading.RLock() + + def _should_suppress_compression(self): + suppress_compression = False + with self._counter_lock: + if self._no_compress_every_n and self._request_counter % self._no_compress_every_n == 0: + suppress_compression = True + self._request_counter += 1 + return suppress_compression + + def SayHello(self, request, context): + if self._should_suppress_compression(): + context.set_response_compression(grpc.Compression.NoCompression) + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def run_server(server_compression, no_compress_every_n, port): + server = grpc.server( + futures.ThreadPoolExecutor(), + compression=server_compression, + options=(('grpc.so_reuseport', 1),)) + helloworld_pb2_grpc.add_GreeterServicer_to_server( + Greeter(no_compress_every_n), server) + address = '{}:{}'.format(_SERVER_HOST, port) + server.add_insecure_port(address) + server.start() + print("Server listening at '{}'".format(address)) + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + server.stop(None) + + +def main(): + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument( + '--server_compression', + default='none', + nargs='?', + choices=_COMPRESSION_OPTIONS.keys(), + help='The default compression method for the server.') + parser.add_argument( + '--no_compress_every_n', + type=int, + default=0, + nargs='?', + help='If set, every nth reply will be uncompressed.') + parser.add_argument( + '--port', + type=int, + default=50051, + nargs='?', + help='The port on which the server will listen.') + args = parser.parse_args() + run_server(_COMPRESSION_OPTIONS[args.server_compression], + args.no_compress_every_n, args.port) + + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/examples/python/compression/test/compression_example_test.py b/examples/python/compression/test/compression_example_test.py new file mode 100644 index 00000000000..7d25379683f --- /dev/null +++ b/examples/python/compression/test/compression_example_test.py @@ -0,0 +1,62 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test for compression example.""" + +import contextlib +import os +import socket +import subprocess +import unittest + +_BINARY_DIR = os.path.realpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) +_SERVER_PATH = os.path.join(_BINARY_DIR, 'server') +_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') + + +@contextlib.contextmanager +def _get_port(): + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0: + raise RuntimeError("Failed to set SO_REUSEPORT.") + sock.bind(('', 0)) + try: + yield sock.getsockname()[1] + finally: + sock.close() + + +class CompressionExampleTest(unittest.TestCase): + + def test_compression_example(self): + with _get_port() as test_port: + server_process = subprocess.Popen((_SERVER_PATH, '--port', + str(test_port), + '--server_compression', 'gzip')) + try: + server_target = 'localhost:{}'.format(test_port) + client_process = subprocess.Popen( + (_CLIENT_PATH, '--server', server_target, + '--channel_compression', 'gzip')) + client_return_code = client_process.wait() + self.assertEqual(0, client_return_code) + self.assertIsNone(server_process.poll()) + finally: + server_process.kill() + server_process.wait() + + +if __name__ == '__main__': + unittest.main(verbosity=2) From 8fb51946bf1a14039f5aab9abeb4144008dfb1e9 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 21 Jun 2019 14:01:27 -0700 Subject: [PATCH 443/676] Fix multiprocessing example for MacOS. A closer reading of the API for getsockopt revealed that we were depending on an implementation detail of getsockopt on Linux. This assumption breaks down on MacOS. getsockopt merely guarantees that it will return on 0 in case of failure and a value greater than 0 in case of success. There is no guarantee as to *which* non-zero value you will receive. On Linux, it seems to be 1, the value which was explicitly set. On MacOS, it seems to be the value of the FLAG which was set, i.e. 512 for SO_REUSEPORT. This commit ensures the check we use does not rely on either of these implementation details. --- examples/python/multiprocessing/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index a05eb9edda0..b1e5951a8b0 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -87,7 +87,7 @@ def _reserve_port(): """Find and reserve a port for all subprocesses to use.""" sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1: + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0: raise RuntimeError("Failed to set SO_REUSEPORT.") sock.bind(('', 0)) try: From bff4dd1b2d6af9e467243b4424999a3c307c0c0c Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 3 Jun 2019 13:45:20 -0700 Subject: [PATCH 444/676] Fast-path for no-error case for grpc_error_get_status. For each client side call, we execute grpc_error_get_status; in the common case that there is no error, we save roughly 30 instructions and a call to strlen. --- .../filters/http/client/http_client_filter.cc | 2 +- .../filters/http/client_authority_filter.cc | 4 +- .../chttp2/transport/hpack_parser.cc | 10 ++-- .../transport/chttp2/transport/hpack_table.cc | 6 ++- .../ext/transport/inproc/inproc_transport.cc | 2 +- src/core/lib/iomgr/error.cc | 24 ++++++--- src/core/lib/slice/slice.cc | 49 +++++++++---------- src/core/lib/slice/slice_internal.h | 15 ++++++ src/core/lib/transport/error_utils.cc | 11 ++++- .../run_tests/sanity/core_banned_functions.py | 1 + 10 files changed, 78 insertions(+), 46 deletions(-) diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc index 4ef6c1f610e..d014460b34e 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -558,7 +558,7 @@ static grpc_slice user_agent_from_args(const grpc_channel_args* args, tmp = gpr_strvec_flatten(&v, nullptr); gpr_strvec_destroy(&v); - result = grpc_slice_intern(grpc_slice_from_static_string(tmp)); + result = grpc_slice_intern(grpc_slice_from_static_string_internal(tmp)); gpr_free(tmp); return result; diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 85b30bc13ca..4bd666ecfee 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -101,8 +101,8 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "GRPC_ARG_DEFAULT_AUTHORITY channel arg. must be a string"); } - chand->default_authority = - grpc_slice_intern(grpc_slice_from_static_string(default_authority_str)); + chand->default_authority = grpc_slice_intern( + grpc_slice_from_static_string_internal(default_authority_str)); chand->default_authority_mdelem = grpc_mdelem_create( GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr); GPR_ASSERT(!args->is_last); diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 7d5c39e5144..8db0c96cc52 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -670,7 +670,7 @@ static grpc_slice take_string(grpc_chttp2_hpack_parser* p, str->copied = true; str->data.referenced = grpc_empty_slice(); } else if (intern) { - s = grpc_slice_intern(grpc_slice_from_static_buffer( + s = grpc_slice_intern(grpc_slice_from_static_buffer_internal( str->data.copied.str, str->data.copied.length)); } else { s = grpc_slice_from_copied_buffer(str->data.copied.str, @@ -1496,14 +1496,14 @@ static grpc_error* parse_key_string(grpc_chttp2_hpack_parser* p, static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) { /* We know that either argument here is a reference counter slice. - * 1. If a result of grpc_slice_from_static_buffer, the refcount is set to - * NoopRefcount. + * 1. If a result of grpc_slice_from_static_buffer_internal, the refcount is + * set to kNoopRefcount. * 2. If it's p->key.data.referenced, then p->key.copied was set to false, * which occurs in begin_parse_string() - where the refcount is set to * p->current_slice_refcount, which is not null. */ return grpc_is_refcounted_slice_binary_header( - p->key.copied ? grpc_slice_from_static_buffer(p->key.data.copied.str, - p->key.data.copied.length) + p->key.copied ? grpc_slice_from_static_buffer_internal( + p->key.data.copied.str, p->key.data.copied.length) : p->key.data.referenced); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index f9e97cc5566..9d1ac4b370f 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/static_metadata.h" @@ -182,9 +183,10 @@ void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) { memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { tbl->static_ents[i - 1] = grpc_mdelem_from_slices( - grpc_slice_intern(grpc_slice_from_static_string(static_table[i].key)), grpc_slice_intern( - grpc_slice_from_static_string(static_table[i].value))); + grpc_slice_from_static_string_internal(static_table[i].key)), + grpc_slice_intern( + grpc_slice_from_static_string_internal(static_table[i].value))); } } diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 8da89851a69..8cb9ac4a2fd 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1203,7 +1203,7 @@ void inproc_transports_create(grpc_transport** server_transport, */ void grpc_inproc_transport_init(void) { grpc_core::ExecCtx exec_ctx; - g_empty_slice = grpc_slice_from_static_buffer(nullptr, 0); + g_empty_slice = grpc_slice_from_static_buffer_internal(nullptr, 0); grpc_slice key_tmp = grpc_slice_from_static_string(":path"); g_fake_path_key = grpc_slice_intern(key_tmp); diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index ebec9dc704a..eb44c9a2c90 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -447,13 +447,17 @@ grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, typedef struct { grpc_status_code code; const char* msg; + size_t len; } special_error_status_map; -static const special_error_status_map error_status_map[] = { - {GRPC_STATUS_OK, ""}, // GRPC_ERROR_NONE - {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_1 - {GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, // GRPC_ERROR_OOM - {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_2 - {GRPC_STATUS_CANCELLED, "Cancelled"}, // GRPC_ERROR_CANCELLED + +const special_error_status_map error_status_map[] = { + {GRPC_STATUS_OK, "", 0}, // GRPC_ERROR_NONE + {GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_1 + {GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory", + strlen("Out of memory")}, // GRPC_ERROR_OOM + {GRPC_STATUS_INVALID_ARGUMENT, "", 0}, // GRPC_ERROR_RESERVED_2 + {GRPC_STATUS_CANCELLED, "Cancelled", + strlen("Cancelled")}, // GRPC_ERROR_CANCELLED }; bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { @@ -483,8 +487,12 @@ bool grpc_error_get_str(grpc_error* err, grpc_error_strs which, grpc_slice* str) { if (grpc_error_is_special(err)) { if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false; - *str = grpc_slice_from_static_string( - error_status_map[reinterpret_cast(err)].msg); + const special_error_status_map& msg = + error_status_map[reinterpret_cast(err)]; + str->refcount = &grpc_core::kNoopRefcount; + str->data.refcounted.bytes = + reinterpret_cast(const_cast(msg.msg)); + str->data.refcounted.length = msg.len; return true; } uint8_t slot = err->strs[which]; diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index eebf66bb882..57862518feb 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -66,32 +66,13 @@ void grpc_slice_unref(grpc_slice slice) { } } +namespace grpc_core { + /* grpc_slice_from_static_string support structure - a refcount that does nothing */ -static grpc_slice_refcount NoopRefcount = - grpc_slice_refcount(grpc_slice_refcount::Type::NOP); - -size_t grpc_slice_memory_usage(grpc_slice s) { - if (s.refcount == nullptr || s.refcount == &NoopRefcount) { - return 0; - } else { - return s.data.refcounted.length; - } -} - -grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { - grpc_slice slice; - slice.refcount = &NoopRefcount; - slice.data.refcounted.bytes = (uint8_t*)s; - slice.data.refcounted.length = len; - return slice; -} - -grpc_slice grpc_slice_from_static_string(const char* s) { - return grpc_slice_from_static_buffer(s, strlen(s)); -} - -namespace grpc_core { +grpc_slice_refcount kNoopRefcount(grpc_slice_refcount::Type::NOP); +static_assert(std::is_trivially_destructible::value, + "kNoopRefcount must be trivially destructible."); /* grpc_slice_new support structures - we create a refcount object extended with the user provided data pointer & destroy function */ @@ -122,6 +103,22 @@ class NewSliceRefcount { } // namespace grpc_core +size_t grpc_slice_memory_usage(grpc_slice s) { + if (s.refcount == nullptr || s.refcount == &grpc_core::kNoopRefcount) { + return 0; + } else { + return s.data.refcounted.length; + } +} + +grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { + return grpc_slice_from_static_buffer_internal(s, len); +} + +grpc_slice grpc_slice_from_static_string(const char* s) { + return grpc_slice_from_static_buffer_internal(s, strlen(s)); +} + grpc_slice grpc_slice_new_with_user_data(void* p, size_t len, void (*destroy)(void*), void* user_data) { @@ -375,10 +372,10 @@ grpc_slice grpc_slice_split_tail_maybe_ref(grpc_slice* source, size_t split, switch (ref_whom) { case GRPC_SLICE_REF_TAIL: tail.refcount = source->refcount->sub_refcount(); - source->refcount = &NoopRefcount; + source->refcount = &grpc_core::kNoopRefcount; break; case GRPC_SLICE_REF_HEAD: - tail.refcount = &NoopRefcount; + tail.refcount = &grpc_core::kNoopRefcount; source->refcount = source->refcount->sub_refcount(); break; case GRPC_SLICE_REF_BOTH: diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index c6943fe6563..54badeb9ab9 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -171,6 +171,8 @@ struct grpc_slice_refcount { namespace grpc_core { +extern grpc_slice_refcount kNoopRefcount; + struct InternedSliceRefcount { static void Destroy(void* arg) { auto* rc = static_cast(arg); @@ -312,4 +314,17 @@ grpc_slice grpc_slice_from_moved_string(grpc_core::UniquePtr p); // 0. All other slices will return the size of the allocated chars. size_t grpc_slice_memory_usage(grpc_slice s); +inline grpc_slice grpc_slice_from_static_buffer_internal(const void* s, + size_t len) { + grpc_slice slice; + slice.refcount = &grpc_core::kNoopRefcount; + slice.data.refcounted.bytes = (uint8_t*)s; + slice.data.refcounted.length = len; + return slice; +} + +inline grpc_slice grpc_slice_from_static_string_internal(const char* s) { + return grpc_slice_from_static_buffer_internal(s, strlen(s)); +} + #endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */ diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index eb4e8c3a282..5be98c9f04f 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -22,6 +22,7 @@ #include #include "src/core/lib/iomgr/error_internal.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/status_conversion.h" static grpc_error* recursively_find_error_with_field(grpc_error* error, @@ -52,7 +53,15 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, if (GPR_LIKELY(error == GRPC_ERROR_NONE)) { if (code != nullptr) *code = GRPC_STATUS_OK; if (slice != nullptr) { - grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice); + // Normally, we call grpc_error_get_str( + // error, GRPC_ERROR_STR_GRPC_MESSAGE, slice). + // We can fastpath since we know that: + // 1) Error is null + // 2) which == GRPC_ERROR_STR_GRPC_MESSAGE + // 3) The resulting slice is statically known. + // 4) Said resulting slice is of length 0 (""). + // This means 3 movs, instead of 10s of instructions and a strlen. + *slice = grpc_slice_from_static_string_internal(""); } if (http_error != nullptr) { *http_error = GRPC_HTTP2_NO_ERROR; diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index ce9ff0dae21..a9c986b3ac2 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -23,6 +23,7 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..')) # map of banned function signature to whitelist BANNED_EXCEPT = { + 'grpc_slice_from_static_buffer(': ['src/core/lib/slice/slice.cc'], 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.cc'], 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/surface/server.cc'], From d73abc7b56d317058b507ab4752a3a0abe65777d Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 16:23:16 -0700 Subject: [PATCH 445/676] Modify comments style --- src/core/lib/gprpp/thd.h | 5 ++--- src/core/lib/gprpp/thd_posix.cc | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 6f29f82427f..0af33faa119 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -64,9 +64,8 @@ class Thread { } bool tracked() const { return tracked_; } - /// Set thread stack size (in bytes). Set to 0 will reset stack size to - /// default value, which is 64KB for Windows threads and 2MB for Posix(x86) - /// threads. + /// Sets thread stack size (in bytes). Sets to 0 will use the default stack + /// size which is 64KB for Windows threads and 2MB for Posix(x86) threads. Options& set_stack_size(size_t bytes) { stack_size_ = bytes; return *this; diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index dbb9c82cb06..7415231e97f 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -55,7 +55,7 @@ size_t RoundUpToPageSize(size_t size) { return (size + page_size - 1) & ~(page_size - 1); } -// Return the minimum valid stack size that can be passed to +// Returns the minimum valid stack size that can be passed to // pthread_attr_setstacksize. size_t MinValidStackSize(size_t request_size) { if (request_size < _SC_THREAD_STACK_MIN) { From a68e7bc4618da2d768582a382ae89bf5d3d76052 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 17:16:29 -0700 Subject: [PATCH 446/676] Remove extra header file, change to c test, change new/delete --- BUILD | 4 +- CMakeLists.txt | 76 ++++++++--------- Makefile | 84 ++++++++----------- build.yaml | 21 +++-- src/core/lib/iomgr/executor/mpmcqueue.cc | 12 --- src/core/lib/iomgr/executor/mpmcqueue.h | 4 +- test/core/iomgr/mpmcqueue_test.cc | 35 ++++---- .../generated/sources_and_headers.json | 34 ++++---- tools/run_tests/generated/tests.json | 48 +++++------ 9 files changed, 141 insertions(+), 177 deletions(-) diff --git a/BUILD b/BUILD index 10933cb24f1..ef485ac4277 100644 --- a/BUILD +++ b/BUILD @@ -782,6 +782,7 @@ grpc_cc_library( "src/core/lib/iomgr/ev_windows.cc", "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -837,7 +838,6 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server_windows.cc", "src/core/lib/iomgr/tcp_uv.cc", "src/core/lib/iomgr/tcp_windows.cc", - "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/time_averaged_stats.cc", "src/core/lib/iomgr/timer.cc", "src/core/lib/iomgr/timer_custom.cc", @@ -940,6 +940,7 @@ grpc_cc_library( "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", @@ -983,7 +984,6 @@ grpc_cc_library( "src/core/lib/iomgr/tcp_server.h", "src/core/lib/iomgr/tcp_server_utils_posix.h", "src/core/lib/iomgr/tcp_windows.h", - "src/core/lib/iomgr/executor/mpmcqueue.h", "src/core/lib/iomgr/time_averaged_stats.h", "src/core/lib/iomgr/timer.h", "src/core/lib/iomgr/timer_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 47d8b3c6d0f..8dc4605297a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -378,6 +378,7 @@ add_dependencies(buildtests_c memory_usage_test) endif() add_dependencies(buildtests_c message_compress_test) add_dependencies(buildtests_c minimal_stack_is_minimal_test) +add_dependencies(buildtests_c mpmcqueue_test) add_dependencies(buildtests_c multiple_server_queues_test) add_dependencies(buildtests_c murmur_hash_test) add_dependencies(buildtests_c no_server_test) @@ -663,7 +664,6 @@ add_dependencies(buildtests_cxx memory_test) add_dependencies(buildtests_cxx message_allocator_end2end_test) add_dependencies(buildtests_cxx metrics_client) add_dependencies(buildtests_cxx mock_test) -add_dependencies(buildtests_cxx mpmcqueue_test) add_dependencies(buildtests_cxx nonblocking_test) add_dependencies(buildtests_cxx noop-benchmark) add_dependencies(buildtests_cxx optional_test) @@ -9364,6 +9364,40 @@ target_link_libraries(minimal_stack_is_minimal_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(mpmcqueue_test + test/core/iomgr/mpmcqueue_test.cc +) + + +target_include_directories(mpmcqueue_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(mpmcqueue_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(mpmcqueue_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(mpmcqueue_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(multiple_server_queues_test test/core/end2end/multiple_server_queues_test.cc ) @@ -15003,46 +15037,6 @@ target_link_libraries(mock_test ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - -add_executable(mpmcqueue_test - test/core/iomgr/mpmcqueue_test.cc - third_party/googletest/googletest/src/gtest-all.cc - third_party/googletest/googlemock/src/gmock-all.cc -) - - -target_include_directories(mpmcqueue_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} - PRIVATE third_party/googletest/googletest/include - PRIVATE third_party/googletest/googletest - PRIVATE third_party/googletest/googlemock/include - PRIVATE third_party/googletest/googlemock - PRIVATE ${_gRPC_PROTO_GENS_DIR} -) - -target_link_libraries(mpmcqueue_test - ${_gRPC_PROTOBUF_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc++_test_util - grpc_test_util - grpc++ - grpc - gpr - ${_gRPC_GFLAGS_LIBRARIES} -) - - endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 6bcf8472d3e..7562a129995 100644 --- a/Makefile +++ b/Makefile @@ -1092,6 +1092,7 @@ memory_usage_server: $(BINDIR)/$(CONFIG)/memory_usage_server memory_usage_test: $(BINDIR)/$(CONFIG)/memory_usage_test message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test minimal_stack_is_minimal_test: $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test +mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test @@ -1240,7 +1241,6 @@ memory_test: $(BINDIR)/$(CONFIG)/memory_test message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test metrics_client: $(BINDIR)/$(CONFIG)/metrics_client mock_test: $(BINDIR)/$(CONFIG)/mock_test -mpmcqueue_test: $(BINDIR)/$(CONFIG)/mpmcqueue_test nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark optional_test: $(BINDIR)/$(CONFIG)/optional_test @@ -1516,6 +1516,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/memory_usage_test \ $(BINDIR)/$(CONFIG)/message_compress_test \ $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test \ + $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/multiple_server_queues_test \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ @@ -1707,7 +1708,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ - $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ $(BINDIR)/$(CONFIG)/optional_test \ @@ -1871,7 +1871,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/message_allocator_end2end_test \ $(BINDIR)/$(CONFIG)/metrics_client \ $(BINDIR)/$(CONFIG)/mock_test \ - $(BINDIR)/$(CONFIG)/mpmcqueue_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ $(BINDIR)/$(CONFIG)/optional_test \ @@ -2112,6 +2111,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 ) $(E) "[RUN] Testing minimal_stack_is_minimal_test" $(Q) $(BINDIR)/$(CONFIG)/minimal_stack_is_minimal_test || ( echo test minimal_stack_is_minimal_test failed ; exit 1 ) + $(E) "[RUN] Testing mpmcqueue_test" + $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing multiple_server_queues_test" $(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 ) $(E) "[RUN] Testing murmur_hash_test" @@ -2374,8 +2375,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing mock_test" $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 ) - $(E) "[RUN] Testing mpmcqueue_test" - $(Q) $(BINDIR)/$(CONFIG)/mpmcqueue_test || ( echo test mpmcqueue_test failed ; exit 1 ) $(E) "[RUN] Testing nonblocking_test" $(Q) $(BINDIR)/$(CONFIG)/nonblocking_test || ( echo test nonblocking_test failed ; exit 1 ) $(E) "[RUN] Testing noop-benchmark" @@ -12131,6 +12130,38 @@ endif endif +MPMCQUEUE_TEST_SRC = \ + test/core/iomgr/mpmcqueue_test.cc \ + +MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(MPMCQUEUE_TEST_OBJS:.o=.dep) +endif +endif + + MULTIPLE_SERVER_QUEUES_TEST_SRC = \ test/core/end2end/multiple_server_queues_test.cc \ @@ -17973,49 +18004,6 @@ endif endif -MPMCQUEUE_TEST_SRC = \ - test/core/iomgr/mpmcqueue_test.cc \ - -MPMCQUEUE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MPMCQUEUE_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/mpmcqueue_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.5.0+. - -$(BINDIR)/$(CONFIG)/mpmcqueue_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/mpmcqueue_test: $(PROTOBUF_DEP) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(MPMCQUEUE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mpmcqueue_test - -endif - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/mpmcqueue_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_mpmcqueue_test: $(MPMCQUEUE_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(MPMCQUEUE_TEST_OBJS:.o=.dep) -endif -endif - - NONBLOCKING_TEST_SRC = \ test/cpp/end2end/nonblocking_test.cc \ diff --git a/build.yaml b/build.yaml index 76447a1bebd..53f40398668 100644 --- a/build.yaml +++ b/build.yaml @@ -3268,6 +3268,16 @@ targets: - grpc - gpr uses_polling: false +- name: mpmcqueue_test + build: test + language: c + src: + - test/core/iomgr/mpmcqueue_test.cc + deps: + - grpc_test_util + - grpc + - gpr + uses_polling: false - name: multiple_server_queues_test build: test language: c @@ -5230,17 +5240,6 @@ targets: - grpc++ - grpc - gpr -- name: mpmcqueue_test - build: test - language: c++ - src: - - test/core/iomgr/mpmcqueue_test.cc - deps: - - grpc++_test_util - - grpc_test_util - - grpc++ - - grpc - - gpr - name: nonblocking_test gtest: true build: test diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 7290c68db94..fff078035c8 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -20,18 +20,6 @@ #include "src/core/lib/iomgr/executor/mpmcqueue.h" -#include -#include -#include -#include -#include -#include -#include - -#include "src/core/lib/debug/stats.h" -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/sync.h" - namespace grpc_core { DebugOnlyTraceFlag thread_pool(false, "thread_pool_trace"); diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 7022cf492f2..6b071a2fd68 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -21,9 +21,6 @@ #include -#include -#include - #include "src/core/lib/debug/stats.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/atomic.h" @@ -80,6 +77,7 @@ class InfLenFIFOQueue : public MPMCQueueInterface { // For Internal Use Only. // Removes the oldest element from the queue and returns it. This routine // will NOT check whether queue is empty, and it will NOT acquire mutex. + // Caller should do the check and acquire mutex before callling. void* PopFront(); struct Node { diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index fdcc2d6019f..f89fed24bc2 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -19,10 +19,7 @@ #include "src/core/lib/iomgr/executor/mpmcqueue.h" #include -#include -#include -#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" @@ -51,9 +48,9 @@ class ProducerThread { ~ProducerThread() { for (int i = 0; i < num_items_; ++i) { GPR_ASSERT(items_[i]->done); - delete items_[i]; + grpc_core::Delete(items_[i]); } - delete[] items_; + gpr_free(items_); } void Start() { thd_.Start(); } @@ -61,9 +58,9 @@ class ProducerThread { private: void Run() { - items_ = new WorkItem*[num_items_]; + items_ = static_cast(gpr_zalloc(num_items_)); for (int i = 0; i < num_items_; ++i) { - items_[i] = new WorkItem(start_index_ + i); + items_[i] = grpc_core::New(start_index_ + i); queue_->Put(items_[i]); } } @@ -105,9 +102,10 @@ static void test_get_empty(void) { thds[i].Start(); } - WorkItem** items = new WorkItem*[THREAD_LARGE_ITERATION]; + WorkItem** items = + static_cast(gpr_zalloc(THREAD_SMALL_ITERATION)); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - items[i] = new WorkItem(i); + items[i] = grpc_core::New(i); queue.Put(static_cast(items[i])); } @@ -121,9 +119,9 @@ static void test_get_empty(void) { gpr_log(GPR_DEBUG, "Checking and Cleaning Up..."); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { GPR_ASSERT(items[i]->done); - delete items[i]; + grpc_core::Delete(items[i]); } - delete[] items; + gpr_free(items); gpr_log(GPR_DEBUG, "Done."); } @@ -131,13 +129,13 @@ static void test_FIFO(void) { gpr_log(GPR_INFO, "test_FIFO"); grpc_core::InfLenFIFOQueue large_queue; for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - large_queue.Put(static_cast(new WorkItem(i))); + large_queue.Put(static_cast(grpc_core::New(i))); } GPR_ASSERT(large_queue.count() == THREAD_LARGE_ITERATION); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { WorkItem* item = static_cast(large_queue.Get()); GPR_ASSERT(i == item->index); - delete item; + grpc_core::Delete(item); } } @@ -146,13 +144,14 @@ static void test_many_thread(void) { const int num_work_thd = 10; const int num_get_thd = 20; grpc_core::InfLenFIFOQueue queue; - ProducerThread** work_thds = new ProducerThread*[num_work_thd]; + ProducerThread** work_thds = + static_cast(gpr_zalloc(num_work_thd)); grpc_core::Thread get_thds[num_get_thd]; gpr_log(GPR_DEBUG, "Fork ProducerThread..."); for (int i = 0; i < num_work_thd; ++i) { - work_thds[i] = new ProducerThread(&queue, i * THREAD_LARGE_ITERATION, - THREAD_LARGE_ITERATION); + work_thds[i] = grpc_core::New( + &queue, i * THREAD_LARGE_ITERATION, THREAD_LARGE_ITERATION); work_thds[i]->Start(); } gpr_log(GPR_DEBUG, "ProducerThread Started."); @@ -178,9 +177,9 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "All Getter Thread Terminated."); gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); for (int i = 0; i < num_work_thd; ++i) { - delete work_thds[i]; + grpc_core::Delete(work_thds[i]); } - delete[] work_thds; + gpr_free(work_thds); gpr_log(GPR_DEBUG, "Done."); } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9bb1ddba930..4e5d5bece82 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1626,6 +1626,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "mpmcqueue_test", + "src": [ + "test/core/iomgr/mpmcqueue_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -4295,24 +4311,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "grpc", - "grpc++", - "grpc++_test_util", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "mpmcqueue_test", - "src": [ - "test/core/iomgr/mpmcqueue_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 29657db49f9..7d1a09dbea8 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -1959,6 +1959,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "mpmcqueue_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -4997,30 +5021,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c++", - "name": "mpmcqueue_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, From 241d77bd80a78594e474d60718bd0f86e4e0f9f4 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 17:18:41 -0700 Subject: [PATCH 447/676] remove extra constant --- test/core/iomgr/mpmcqueue_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index f89fed24bc2..38c899e7098 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -23,7 +23,6 @@ #include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" -#define THREAD_SMALL_ITERATION 100 #define THREAD_LARGE_ITERATION 10000 // Testing items for queue @@ -103,7 +102,7 @@ static void test_get_empty(void) { } WorkItem** items = - static_cast(gpr_zalloc(THREAD_SMALL_ITERATION)); + static_cast(gpr_zalloc(THREAD_LARGE_ITERATION)); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { items[i] = grpc_core::New(i); queue.Put(static_cast(items[i])); From 9427d1c9ce2f7bfa1802a43b176184ee1894032f Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 21 Jun 2019 17:24:05 -0700 Subject: [PATCH 448/676] Revert "Surface exceptions in gevent IO manager" --- .../grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi | 44 +++++++++---------- .../grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi | 42 +++++++++--------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index 59b3891d9fa..30fdf6a7600 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -44,12 +44,12 @@ cdef extern from "src/core/lib/iomgr/resolve_address_custom.h": pass struct grpc_custom_resolver_vtable: - grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res) except * - void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port) except * + grpc_error* (*resolve)(char* host, char* port, grpc_resolved_addresses** res); + void (*resolve_async)(grpc_custom_resolver* resolver, char* host, char* port); void grpc_custom_resolve_callback(grpc_custom_resolver* resolver, grpc_resolved_addresses* result, - grpc_error* error) + grpc_error* error); cdef extern from "src/core/lib/iomgr/tcp_custom.h": struct grpc_custom_socket: @@ -67,25 +67,25 @@ cdef extern from "src/core/lib/iomgr/tcp_custom.h": ctypedef void (*grpc_custom_close_callback)(grpc_custom_socket* socket) struct grpc_socket_vtable: - grpc_error* (*init)(grpc_custom_socket* socket, int domain) except * + grpc_error* (*init)(grpc_custom_socket* socket, int domain); void (*connect)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, grpc_custom_connect_callback cb) except * - void (*destroy)(grpc_custom_socket* socket) except * - void (*shutdown)(grpc_custom_socket* socket) except * - void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb) except * + size_t len, grpc_custom_connect_callback cb); + void (*destroy)(grpc_custom_socket* socket); + void (*shutdown)(grpc_custom_socket* socket); + void (*close)(grpc_custom_socket* socket, grpc_custom_close_callback cb); void (*write)(grpc_custom_socket* socket, grpc_slice_buffer* slices, - grpc_custom_write_callback cb) except * + grpc_custom_write_callback cb); void (*read)(grpc_custom_socket* socket, char* buffer, size_t length, - grpc_custom_read_callback cb) except * + grpc_custom_read_callback cb); grpc_error* (*getpeername)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len) except * + const grpc_sockaddr* addr, int* len); grpc_error* (*getsockname)(grpc_custom_socket* socket, - const grpc_sockaddr* addr, int* len) except * + const grpc_sockaddr* addr, int* len); grpc_error* (*bind)(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags) except * - grpc_error* (*listen)(grpc_custom_socket* socket) except * + size_t len, int flags); + grpc_error* (*listen)(grpc_custom_socket* socket); void (*accept)(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb) except * + grpc_custom_accept_callback cb); cdef extern from "src/core/lib/iomgr/timer_custom.h": struct grpc_custom_timer: @@ -94,17 +94,17 @@ cdef extern from "src/core/lib/iomgr/timer_custom.h": # We don't care about the rest of the fields struct grpc_custom_timer_vtable: - void (*start)(grpc_custom_timer* t) except * - void (*stop)(grpc_custom_timer* t) except * + void (*start)(grpc_custom_timer* t); + void (*stop)(grpc_custom_timer* t); - void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error) + void grpc_custom_timer_callback(grpc_custom_timer* t, grpc_error* error); cdef extern from "src/core/lib/iomgr/pollset_custom.h": struct grpc_custom_poller_vtable: - void (*init)() except * - void (*poll)(size_t timeout_ms) except * - void (*kick)() except * - void (*shutdown)() except * + void (*init)() + void (*poll)(size_t timeout_ms) + void (*kick)() + void (*shutdown)() cdef extern from "src/core/lib/iomgr/iomgr_custom.h": void grpc_custom_iomgr_init(grpc_socket_vtable* socket, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi index f82fca2cce7..a1618d04d0e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi @@ -56,7 +56,7 @@ cdef sockaddr_is_ipv4(const grpc_sockaddr* address, size_t length): c_addr.len = length return grpc_sockaddr_get_uri_scheme(&c_addr) == b'ipv4' -cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups) except *: +cdef grpc_resolved_addresses* tuples_to_resolvaddr(tups): cdef grpc_resolved_addresses* addresses tups_set = set((tup[4][0], tup[4][1]) for tup in tups) addresses = malloc(sizeof(grpc_resolved_addresses)) @@ -84,7 +84,7 @@ cdef class SocketWrapper: self.c_buffer = NULL self.len = 0 -cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) except * with gil: +cdef grpc_error* socket_init(grpc_custom_socket* socket, int domain) with gil: sw = SocketWrapper() sw.c_socket = socket sw.sockopts = [] @@ -112,7 +112,7 @@ def socket_connect_async(socket_wrapper, addr_tuple): cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, size_t addr_len, - grpc_custom_connect_callback cb) except * with gil: + grpc_custom_connect_callback cb) with gil: py_socket = None socket_wrapper = socket.impl socket_wrapper.connect_cb = cb @@ -125,10 +125,10 @@ cdef void socket_connect(grpc_custom_socket* socket, const grpc_sockaddr* addr, socket_wrapper.socket = py_socket _spawn_greenlet(socket_connect_async, socket_wrapper, addr_tuple) -cdef void socket_destroy(grpc_custom_socket* socket) except * with gil: +cdef void socket_destroy(grpc_custom_socket* socket) with gil: cpython.Py_DECREF(socket.impl) -cdef void socket_shutdown(grpc_custom_socket* socket) except * with gil: +cdef void socket_shutdown(grpc_custom_socket* socket) with gil: try: (socket.impl).socket.shutdown(gevent_socket.SHUT_RDWR) except IOError as io_error: @@ -136,7 +136,7 @@ cdef void socket_shutdown(grpc_custom_socket* socket) except * with gil: raise io_error cdef void socket_close(grpc_custom_socket* socket, - grpc_custom_close_callback cb) except * with gil: + grpc_custom_close_callback cb) with gil: socket_wrapper = (socket.impl) if socket_wrapper.socket is not None: socket_wrapper.socket.close() @@ -176,7 +176,7 @@ def socket_write_async(socket_wrapper, write_bytes): socket_write_async_cython(socket_wrapper, write_bytes) cdef void socket_write(grpc_custom_socket* socket, grpc_slice_buffer* buffer, - grpc_custom_write_callback cb) except * with gil: + grpc_custom_write_callback cb) with gil: cdef char* start sw = socket.impl sw.write_cb = cb @@ -204,7 +204,7 @@ def socket_read_async(socket_wrapper): socket_read_async_cython(socket_wrapper) cdef void socket_read(grpc_custom_socket* socket, char* buffer, - size_t length, grpc_custom_read_callback cb) except * with gil: + size_t length, grpc_custom_read_callback cb) with gil: sw = socket.impl sw.read_cb = cb sw.c_buffer = buffer @@ -213,7 +213,7 @@ cdef void socket_read(grpc_custom_socket* socket, char* buffer, cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) except * with gil: + int* length) with gil: cdef char* src_buf peer = (socket.impl).socket.getpeername() @@ -226,7 +226,7 @@ cdef grpc_error* socket_getpeername(grpc_custom_socket* socket, cdef grpc_error* socket_getsockname(grpc_custom_socket* socket, const grpc_sockaddr* addr, - int* length) except * with gil: + int* length) with gil: cdef char* src_buf cdef grpc_resolved_address c_addr if (socket.impl).socket is None: @@ -245,7 +245,7 @@ def applysockopts(s): cdef grpc_error* socket_bind(grpc_custom_socket* socket, const grpc_sockaddr* addr, - size_t len, int flags) except * with gil: + size_t len, int flags) with gil: addr_tuple = sockaddr_to_tuple(addr, len) try: try: @@ -262,7 +262,7 @@ cdef grpc_error* socket_bind(grpc_custom_socket* socket, else: return grpc_error_none() -cdef grpc_error* socket_listen(grpc_custom_socket* socket) except * with gil: +cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil: (socket.impl).socket.listen(50) return grpc_error_none() @@ -292,7 +292,7 @@ def socket_accept_async(s): accept_callback_cython(s) cdef void socket_accept(grpc_custom_socket* socket, grpc_custom_socket* client, - grpc_custom_accept_callback cb) except * with gil: + grpc_custom_accept_callback cb) with gil: sw = socket.impl sw.accepting_socket = client sw.accept_cb = cb @@ -322,7 +322,7 @@ cdef socket_resolve_async_cython(ResolveWrapper resolve_wrapper): def socket_resolve_async_python(resolve_wrapper): socket_resolve_async_cython(resolve_wrapper) -cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) except * with gil: +cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) with gil: rw = ResolveWrapper() rw.c_resolver = r rw.c_host = host @@ -330,7 +330,7 @@ cdef void socket_resolve_async(grpc_custom_resolver* r, char* host, char* port) _spawn_greenlet(socket_resolve_async_python, rw) cdef grpc_error* socket_resolve(char* host, char* port, - grpc_resolved_addresses** res) except * with gil: + grpc_resolved_addresses** res) with gil: try: result = gevent_socket.getaddrinfo(host, port) res[0] = tuples_to_resolvaddr(result) @@ -360,13 +360,13 @@ cdef class TimerWrapper: self.event.set() self.timer.stop() -cdef void timer_start(grpc_custom_timer* t) except * with gil: +cdef void timer_start(grpc_custom_timer* t) with gil: timer = TimerWrapper(t.timeout_ms / 1000.0) timer.c_timer = t t.timer = timer timer.start() -cdef void timer_stop(grpc_custom_timer* t) except * with gil: +cdef void timer_stop(grpc_custom_timer* t) with gil: time_wrapper = t.timer time_wrapper.stop() @@ -374,16 +374,16 @@ cdef void timer_stop(grpc_custom_timer* t) except * with gil: ### pollset implementation ### ############################### -cdef void init_loop() except * with gil: +cdef void init_loop() with gil: pass -cdef void destroy_loop() except * with gil: +cdef void destroy_loop() with gil: g_pool.join() -cdef void kick_loop() except * with gil: +cdef void kick_loop() with gil: g_event.set() -cdef void run_loop(size_t timeout_ms) except * with gil: +cdef void run_loop(size_t timeout_ms) with gil: timeout = timeout_ms / 1000.0 if timeout_ms > 0: g_event.wait(timeout) From 7a957698be3efdcc9bedf73972f9fd204e6b4cb0 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 17:32:40 -0700 Subject: [PATCH 449/676] Modify clock type and time measurement --- src/core/lib/iomgr/executor/mpmcqueue.cc | 32 +++++++++++++----------- src/core/lib/iomgr/executor/mpmcqueue.h | 23 ++++++++--------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index fff078035c8..78a3aa1306f 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -25,6 +25,8 @@ namespace grpc_core { DebugOnlyTraceFlag thread_pool(false, "thread_pool_trace"); inline void* InfLenFIFOQueue::PopFront() { + // Caller should already checked queue is not empty and has already hold the + // mutex. This function will only do the job of removal. void* result = queue_head_->content; Node* head_to_remove = queue_head_; queue_head_ = queue_head_->next; @@ -33,29 +35,29 @@ inline void* InfLenFIFOQueue::PopFront() { if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { gpr_timespec wait_time = - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), head_to_remove->insert_time); + gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), head_to_remove->insert_time); // Updates Stats info stats_.num_completed++; - stats_.total_queue_cycles = - gpr_time_add(stats_.total_queue_cycles, wait_time); - stats_.max_queue_cycles = gpr_time_max( - gpr_convert_clock_type(stats_.max_queue_cycles, GPR_TIMESPAN), + stats_.total_queue_time = + gpr_time_add(stats_.total_queue_time, wait_time); + stats_.max_queue_time = gpr_time_max( + gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), wait_time); if (count_.Load(MemoryOrder::RELAXED) == 0) { - stats_.busy_time_cycles = - gpr_time_add(stats_.busy_time_cycles, - gpr_time_sub(gpr_now(GPR_CLOCK_PRECISE), busy_time)); + stats_.busy_queue_time = + gpr_time_add(stats_.busy_queue_time, + gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), busy_time)); } gpr_log(GPR_INFO, - "[InfLenFIFOQueue Get] num_completed: %" PRIu64 - " total_queue_cycles: %" PRId32 " max_queue_cycles: %" PRId32 - " busy_time_cycles: %" PRId32, - stats_.num_completed, gpr_time_to_millis(stats_.total_queue_cycles), - gpr_time_to_millis(stats_.max_queue_cycles), - gpr_time_to_millis(stats_.busy_time_cycles)); + "[InfLenFIFOQueue PopFront] num_completed: %" PRIu64 + " total_queue_time: %f max_queue_time: %f busy_queue_time: %f", + stats_.num_completed, + gpr_timespec_to_micros(stats_.total_queue_time), + gpr_timespec_to_micros(stats_.max_queue_time), + gpr_timespec_to_micros(stats_.busy_queue_time)); } Delete(head_to_remove); @@ -81,7 +83,7 @@ void InfLenFIFOQueue::Put(void* elem) { Node* new_node = New(elem); if (count_.Load(MemoryOrder::RELAXED) == 0) { if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { - busy_time = gpr_now(GPR_CLOCK_PRECISE); + busy_time = gpr_now(GPR_CLOCK_MONOTONIC); } queue_head_ = queue_tail_ = new_node; } else { diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 6b071a2fd68..208038498c9 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -52,8 +52,7 @@ class MPMCQueueInterface { class InfLenFIFOQueue : public MPMCQueueInterface { public: - // Creates a new MPMC Queue. The queue created - // will have infinite length. + // Creates a new MPMC Queue. The queue created will have infinite length. InfLenFIFOQueue(); // Releases all resources hold by the queue. The queue must be empty, and no @@ -92,24 +91,24 @@ class InfLenFIFOQueue : public MPMCQueueInterface { }; // Stats of queue. This will only be collect when debug trace mode is on. - // All printed stats info will have time measurement in millisecond. + // All printed stats info will have time measurement in microsecond. struct Stats { uint64_t num_started; // Number of elements have been added to queue uint64_t num_completed; // Number of elements have been removed from // the queue - gpr_timespec total_queue_cycles; // Total waiting time that all the - // removed elements have spent in queue - gpr_timespec max_queue_cycles; // Max waiting time among all removed - // elements - gpr_timespec busy_time_cycles; // Accumulated amount of time that queue - // was not empty + gpr_timespec total_queue_time; // Total waiting time that all the + // removed elements have spent in queue + gpr_timespec max_queue_time; // Max waiting time among all removed + // elements + gpr_timespec busy_queue_time; // Accumulated amount of time that queue + // was not empty Stats() { num_started = 0; num_completed = 0; - total_queue_cycles = gpr_time_0(GPR_TIMESPAN); - max_queue_cycles = gpr_time_0(GPR_TIMESPAN); - busy_time_cycles = gpr_time_0(GPR_TIMESPAN); + total_queue_time = gpr_time_0(GPR_TIMESPAN); + max_queue_time = gpr_time_0(GPR_TIMESPAN); + busy_queue_time = gpr_time_0(GPR_TIMESPAN); } }; From 723d6580bd381aa46fcaac029fa9246ff48f9319 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 17:46:16 -0700 Subject: [PATCH 450/676] Change to malloc --- test/core/iomgr/mpmcqueue_test.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 38c899e7098..42852b8b583 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -41,7 +41,7 @@ class ProducerThread { : start_index_(start_index), num_items_(num_items), queue_(queue) { items_ = nullptr; thd_ = grpc_core::Thread( - "mpmcq_test_mt_put_thd", + "mpmcq_test_put_thd", [](void* th) { static_cast(th)->Run(); }, this); } ~ProducerThread() { @@ -57,7 +57,8 @@ class ProducerThread { private: void Run() { - items_ = static_cast(gpr_zalloc(num_items_)); + items_ = + static_cast(gpr_malloc(num_items_ * sizeof(WorkItem*))); for (int i = 0; i < num_items_; ++i) { items_[i] = grpc_core::New(start_index_ + i); queue_->Put(items_[i]); @@ -101,8 +102,8 @@ static void test_get_empty(void) { thds[i].Start(); } - WorkItem** items = - static_cast(gpr_zalloc(THREAD_LARGE_ITERATION)); + WorkItem** items = static_cast( + gpr_malloc(THREAD_LARGE_ITERATION * sizeof(WorkItem*))); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { items[i] = grpc_core::New(i); queue.Put(static_cast(items[i])); @@ -143,8 +144,8 @@ static void test_many_thread(void) { const int num_work_thd = 10; const int num_get_thd = 20; grpc_core::InfLenFIFOQueue queue; - ProducerThread** work_thds = - static_cast(gpr_zalloc(num_work_thd)); + ProducerThread** work_thds = static_cast( + gpr_malloc(num_work_thd * sizeof(ProducerThread*))); grpc_core::Thread get_thds[num_get_thd]; gpr_log(GPR_DEBUG, "Fork ProducerThread..."); From 2a7e593ac4ed4a4eefb1c764d3b1e54879fe38fc Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 18:03:29 -0700 Subject: [PATCH 451/676] Change consumer thread to class --- test/core/iomgr/mpmcqueue_test.cc | 72 ++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 42852b8b583..792d9b602c2 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -58,7 +58,7 @@ class ProducerThread { private: void Run() { items_ = - static_cast(gpr_malloc(num_items_ * sizeof(WorkItem*))); + static_cast(gpr_zalloc(num_items_ * sizeof(WorkItem*))); for (int i = 0; i < num_items_; ++i) { items_[i] = grpc_core::New(start_index_ + i); queue_->Put(items_[i]); @@ -72,38 +72,52 @@ class ProducerThread { WorkItem** items_; }; -static void ConsumerThread(void* args) { - grpc_core::InfLenFIFOQueue* queue = - static_cast(args); +class ConsumerThread { + public: + ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) { + thd_ = grpc_core::Thread( + "mpmcq_test_get_thd", + [](void* th) { static_cast(th)->Run(); }, this); + } + ~ConsumerThread() {} - // count number of Get() called in this thread - int count = 0; + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } - WorkItem* item; - while ((item = static_cast(queue->Get())) != nullptr) { - count++; - GPR_ASSERT(!item->done); - item->done = true; - } + private: + void Run() { + // count number of Get() called in this thread + int count = 0; + + WorkItem* item; + while ((item = static_cast(queue_->Get())) != nullptr) { + count++; + GPR_ASSERT(!item->done); + item->done = true; + } - gpr_log(GPR_DEBUG, "ConsumerThread: %d times of Get() called.", count); -} + gpr_log(GPR_DEBUG, "ConsumerThread: %d times of Get() called.", count); + } + grpc_core::InfLenFIFOQueue* queue_; + grpc_core::Thread thd_; +}; static void test_get_empty(void) { gpr_log(GPR_INFO, "test_get_empty"); grpc_core::InfLenFIFOQueue queue; GPR_ASSERT(queue.count() == 0); const int num_threads = 10; - grpc_core::Thread thds[num_threads]; + ConsumerThread** consumer_thds = static_cast( + gpr_zalloc(num_threads * sizeof(ConsumerThread*))); // Fork threads. Threads should block at the beginning since queue is empty. for (int i = 0; i < num_threads; ++i) { - thds[i] = grpc_core::Thread("mpmcq_test_ge_thd", ConsumerThread, &queue); - thds[i].Start(); + consumer_thds[i] = grpc_core::New(&queue); + consumer_thds[i]->Start(); } WorkItem** items = static_cast( - gpr_malloc(THREAD_LARGE_ITERATION * sizeof(WorkItem*))); + gpr_zalloc(THREAD_LARGE_ITERATION * sizeof(WorkItem*))); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { items[i] = grpc_core::New(i); queue.Put(static_cast(items[i])); @@ -114,7 +128,7 @@ static void test_get_empty(void) { queue.Put(nullptr); } for (int i = 0; i < num_threads; ++i) { - thds[i].Join(); + consumer_thds[i]->Join(); } gpr_log(GPR_DEBUG, "Checking and Cleaning Up..."); for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { @@ -122,6 +136,10 @@ static void test_get_empty(void) { grpc_core::Delete(items[i]); } gpr_free(items); + for (int i = 0; i < num_threads; ++i) { + grpc_core::Delete(consumer_thds[i]); + } + gpr_free(consumer_thds); gpr_log(GPR_DEBUG, "Done."); } @@ -145,8 +163,9 @@ static void test_many_thread(void) { const int num_get_thd = 20; grpc_core::InfLenFIFOQueue queue; ProducerThread** work_thds = static_cast( - gpr_malloc(num_work_thd * sizeof(ProducerThread*))); - grpc_core::Thread get_thds[num_get_thd]; + gpr_zalloc(num_work_thd * sizeof(ProducerThread*))); + ConsumerThread** consumer_thds = static_cast( + gpr_zalloc(num_get_thd * sizeof(ConsumerThread*))); gpr_log(GPR_DEBUG, "Fork ProducerThread..."); for (int i = 0; i < num_work_thd; ++i) { @@ -157,9 +176,8 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "ProducerThread Started."); gpr_log(GPR_DEBUG, "Fork Getter Thread..."); for (int i = 0; i < num_get_thd; ++i) { - get_thds[i] = - grpc_core::Thread("mpmcq_test_mt_get_thd", ConsumerThread, &queue); - get_thds[i].Start(); + consumer_thds[i] = grpc_core::New(&queue); + consumer_thds[i]->Start(); } gpr_log(GPR_DEBUG, "Getter Thread Started."); gpr_log(GPR_DEBUG, "Waiting ProducerThread to finish..."); @@ -172,7 +190,7 @@ static void test_many_thread(void) { queue.Put(nullptr); } for (int i = 0; i < num_get_thd; ++i) { - get_thds[i].Join(); + consumer_thds[i]->Join(); } gpr_log(GPR_DEBUG, "All Getter Thread Terminated."); gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); @@ -180,6 +198,10 @@ static void test_many_thread(void) { grpc_core::Delete(work_thds[i]); } gpr_free(work_thds); + for (int i = 0; i < num_get_thd; ++i) { + grpc_core::Delete(consumer_thds[i]); + } + gpr_free(consumer_thds); gpr_log(GPR_DEBUG, "Done."); } From 5c95bcbd83db1b8d0d379ab608c445d93a98532b Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 18:06:11 -0700 Subject: [PATCH 452/676] Default value in class --- src/core/lib/iomgr/executor/mpmcqueue.cc | 3 +-- src/core/lib/iomgr/executor/mpmcqueue.h | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 78a3aa1306f..df8dd13e3e2 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -69,8 +69,7 @@ inline void* InfLenFIFOQueue::PopFront() { return result; } -InfLenFIFOQueue::InfLenFIFOQueue() - : num_waiters_(0), queue_head_(nullptr), queue_tail_(nullptr) {} +InfLenFIFOQueue::InfLenFIFOQueue() {} InfLenFIFOQueue::~InfLenFIFOQueue() { GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 208038498c9..964ac6a8b41 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -114,13 +114,13 @@ class InfLenFIFOQueue : public MPMCQueueInterface { Mutex mu_; // Protecting lock CondVar wait_nonempty_; // Wait on empty queue on get - int num_waiters_; // Number of waiters + int num_waiters_ = 0; // Number of waiters - Node* queue_head_; // Head of the queue, remove position - Node* queue_tail_; // End of queue, insert position - Atomic count_{0}; // Number of elements in queue - Stats stats_; // Stats info - gpr_timespec busy_time; // Start time of busy queue + Node* queue_head_ = nullptr; // Head of the queue, remove position + Node* queue_tail_ = nullptr; // End of queue, insert position + Atomic count_{0}; // Number of elements in queue + Stats stats_; // Stats info + gpr_timespec busy_time; // Start time of busy queue }; } // namespace grpc_core From 1bda5ce33865ca6227ee980a848b5e2069a3b11d Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 21 Jun 2019 18:08:30 -0700 Subject: [PATCH 453/676] clang_format --- src/core/lib/iomgr/executor/mpmcqueue.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index df8dd13e3e2..cf8ade721d3 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -39,11 +39,9 @@ inline void* InfLenFIFOQueue::PopFront() { // Updates Stats info stats_.num_completed++; - stats_.total_queue_time = - gpr_time_add(stats_.total_queue_time, wait_time); + stats_.total_queue_time = gpr_time_add(stats_.total_queue_time, wait_time); stats_.max_queue_time = gpr_time_max( - gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), - wait_time); + gpr_convert_clock_type(stats_.max_queue_time, GPR_TIMESPAN), wait_time); if (count_.Load(MemoryOrder::RELAXED) == 0) { stats_.busy_queue_time = From 8b91dc5fd2683424efbb32ed02cf6acdce95fecd Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Sat, 22 Jun 2019 17:09:34 -0700 Subject: [PATCH 454/676] Move more of usage to grpc_impl 1) Create server_context_impl and completion_queue_impl headers. 2) Move more of usage of ClientContext, ServerContext to grpc_impl --- BUILD | 3 ++ BUILD.gn | 2 ++ CMakeLists.txt | 6 ++++ Makefile | 6 ++++ build.yaml | 2 ++ gRPC-C++.podspec | 2 ++ include/grpcpp/completion_queue_impl.h | 24 +++++++++++++ .../impl/codegen/async_generic_service.h | 4 +-- include/grpcpp/impl/codegen/async_stream.h | 35 +++++++++--------- include/grpcpp/impl/codegen/call_op_set.h | 8 ++--- include/grpcpp/impl/codegen/client_callback.h | 36 +++++++++---------- .../grpcpp/impl/codegen/intercepted_channel.h | 2 +- .../grpcpp/impl/codegen/server_interface.h | 3 +- include/grpcpp/server_context_impl.h | 24 +++++++++++++ include/grpcpp/server_impl.h | 2 +- tools/doxygen/Doxyfile.c++ | 2 ++ tools/doxygen/Doxyfile.c++.internal | 2 ++ .../generated/sources_and_headers.json | 4 +++ 18 files changed, 123 insertions(+), 44 deletions(-) create mode 100644 include/grpcpp/completion_queue_impl.h create mode 100644 include/grpcpp/server_context_impl.h diff --git a/BUILD b/BUILD index 8fd52808400..35e10a8b2ff 100644 --- a/BUILD +++ b/BUILD @@ -222,6 +222,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -264,6 +265,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_context_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", @@ -2187,6 +2189,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", + "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", diff --git a/BUILD.gn b/BUILD.gn index e5396f51426..534c88bd67f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1028,6 +1028,7 @@ config("grpc_config") { "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -1118,6 +1119,7 @@ config("grpc_config") { "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a34f9265256..46bd48cccdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3160,6 +3160,7 @@ foreach(_hdr include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h + include/grpcpp/completion_queue_impl.h include/grpcpp/create_channel.h include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h @@ -3199,6 +3200,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h @@ -3781,6 +3783,7 @@ foreach(_hdr include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h + include/grpcpp/completion_queue_impl.h include/grpcpp/create_channel.h include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h @@ -3820,6 +3823,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h @@ -4780,6 +4784,7 @@ foreach(_hdr include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h + include/grpcpp/completion_queue_impl.h include/grpcpp/create_channel.h include/grpcpp/create_channel_impl.h include/grpcpp/create_channel_posix.h @@ -4819,6 +4824,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h diff --git a/Makefile b/Makefile index 9930fc35a25..702c571f585 100644 --- a/Makefile +++ b/Makefile @@ -5534,6 +5534,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ + include/grpcpp/completion_queue_impl.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ @@ -5573,6 +5574,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ @@ -6163,6 +6165,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ + include/grpcpp/completion_queue_impl.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ @@ -6202,6 +6205,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ @@ -7111,6 +7115,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ + include/grpcpp/completion_queue_impl.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ @@ -7150,6 +7155,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/build.yaml b/build.yaml index dad2146bd1c..d63284e1267 100644 --- a/build.yaml +++ b/build.yaml @@ -1366,6 +1366,7 @@ filegroups: - include/grpcpp/channel_impl.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h + - include/grpcpp/completion_queue_impl.h - include/grpcpp/create_channel.h - include/grpcpp/create_channel_impl.h - include/grpcpp/create_channel_posix.h @@ -1405,6 +1406,7 @@ filegroups: - include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h + - include/grpcpp/server_context_impl.h - include/grpcpp/server_impl.h - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index f0a4418b20c..981fb345eee 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -85,6 +85,7 @@ Pod::Spec.new do |s| 'include/grpcpp/channel_impl.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', + 'include/grpcpp/completion_queue_impl.h', 'include/grpcpp/create_channel.h', 'include/grpcpp/create_channel_impl.h', 'include/grpcpp/create_channel_posix.h', @@ -124,6 +125,7 @@ Pod::Spec.new do |s| 'include/grpcpp/server_builder.h', 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', + 'include/grpcpp/server_context_impl.h', 'include/grpcpp/server_impl.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', diff --git a/include/grpcpp/completion_queue_impl.h b/include/grpcpp/completion_queue_impl.h new file mode 100644 index 00000000000..d5bb07d5763 --- /dev/null +++ b/include/grpcpp/completion_queue_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_COMPLETION_QUEUE_H +#define GRPCPP_COMPLETION_QUEUE_H + +#include + +#endif // GRPCPP_COMPLETION_QUEUE_H diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 46d09121a7b..95c0f3dd969 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -33,7 +33,7 @@ typedef ServerAsyncResponseWriter GenericServerAsyncResponseWriter; typedef ServerAsyncReader GenericServerAsyncReader; typedef ServerAsyncWriter GenericServerAsyncWriter; -class GenericServerContext final : public ServerContext { +class GenericServerContext final : public grpc_impl::ServerContext { public: const grpc::string& method() const { return method_; } const grpc::string& host() const { return host_; } @@ -99,7 +99,7 @@ class ServerGenericBidiReactor virtual void OnStarted(GenericServerContext* context) {} private: - void OnStarted(ServerContext* ctx) final { + void OnStarted(grpc_impl::ServerContext* ctx) final { OnStarted(static_cast(ctx)); } }; diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index f95772650a2..5e608df5c4e 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -181,8 +181,8 @@ class ClientAsyncReaderFactory { static ClientAsyncReader* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const W& request, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + const W& request, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncReader))) @@ -260,8 +260,9 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { private: friend class internal::ClientAsyncReaderFactory; template - ClientAsyncReader(::grpc::internal::Call call, ClientContext* context, - const W& request, bool start, void* tag) + ClientAsyncReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, + bool start, void* tag) : context_(context), call_(call), started_(start) { // TODO(ctiller): don't assert GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); @@ -280,7 +281,7 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { call_.PerformOps(&init_ops_); } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, @@ -329,8 +330,8 @@ class ClientAsyncWriterFactory { static ClientAsyncWriter* Create(ChannelInterface* channel, CompletionQueue* cq, const ::grpc::internal::RpcMethod& method, - ClientContext* context, R* response, - bool start, void* tag) { + ::grpc_impl::ClientContext* context, + R* response, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( call.call(), sizeof(ClientAsyncWriter))) @@ -426,8 +427,9 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { private: friend class internal::ClientAsyncWriterFactory; template - ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context, - R* response, bool start, void* tag) + ClientAsyncWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, R* response, + bool start, void* tag) : context_(context), call_(call), started_(start) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); @@ -449,7 +451,7 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> @@ -493,8 +495,8 @@ class ClientAsyncReaderWriterFactory { /// used to send to the server when starting the call. static ClientAsyncReaderWriter* Create( ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, ClientContext* context, - bool start, void* tag) { + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, bool start, void* tag) { ::grpc::internal::Call call = channel->CreateCall(method, context, cq); return new (g_core_codegen_interface->grpc_call_arena_alloc( @@ -599,8 +601,9 @@ class ClientAsyncReaderWriter final private: friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context, - bool start, void* tag) + ClientAsyncReaderWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, bool start, + void* tag) : context_(context), call_(call), started_(start) { if (start) { StartCallInternal(tag); @@ -620,7 +623,7 @@ class ClientAsyncReaderWriter final } } - ClientContext* context_; + ::grpc_impl::ClientContext* context_; ::grpc::internal::Call call_; bool started_; ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index c3ae6c4e3d2..d0958bbb251 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -697,7 +697,7 @@ class CallOpRecvInitialMetadata { public: CallOpRecvInitialMetadata() : metadata_map_(nullptr) {} - void RecvInitialMetadata(ClientContext* context) { + void RecvInitialMetadata(::grpc_impl::ClientContext* context) { context->initial_metadata_received_ = true; metadata_map_ = &context->recv_initial_metadata_; } @@ -746,7 +746,7 @@ class CallOpClientRecvStatus { CallOpClientRecvStatus() : recv_status_(nullptr), debug_error_string_(nullptr) {} - void ClientRecvStatus(ClientContext* context, Status* status) { + void ClientRecvStatus(::grpc_impl::ClientContext* context, Status* status) { client_context_ = context; metadata_map_ = &client_context_->trailing_metadata_; recv_status_ = status; @@ -807,7 +807,7 @@ class CallOpClientRecvStatus { private: bool hijacked_ = false; - ClientContext* client_context_; + ::grpc_impl::ClientContext* client_context_; MetadataMap* metadata_map_; Status* recv_status_; const char* debug_error_string_; diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 86d06b72c91..9441a48b051 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -44,8 +44,8 @@ class RpcMethod; /// TODO(vjpai): Combine as much as possible with the blocking unary call code template void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CallbackUnaryCallImpl x( channel, method, context, request, result, on_completion); @@ -55,8 +55,8 @@ template class CallbackUnaryCallImpl { public: CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const InputMessage* request, - OutputMessage* result, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, std::function on_completion) { CompletionQueue* cq = channel->CallbackCQ(); GPR_CODEGEN_ASSERT(cq != nullptr); @@ -550,7 +550,7 @@ class ClientCallbackReaderWriterImpl friend class ClientCallbackReaderWriterFactory; ClientCallbackReaderWriterImpl( - Call call, ClientContext* context, + Call call, ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) : context_(context), call_(call), @@ -559,7 +559,7 @@ class ClientCallbackReaderWriterImpl this->BindReactor(reactor); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientBidiReactor* const reactor_; @@ -594,7 +594,7 @@ class ClientCallbackReaderWriterFactory { public: static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, + ::grpc_impl::ClientContext* context, ::grpc::experimental::ClientBidiReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -692,7 +692,7 @@ class ClientCallbackReaderImpl template ClientCallbackReaderImpl( - Call call, ClientContext* context, Request* request, + Call call, ::grpc_impl::ClientContext* context, Request* request, ::grpc::experimental::ClientReadReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -701,7 +701,7 @@ class ClientCallbackReaderImpl start_ops_.ClientSendClose(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientReadReactor* const reactor_; @@ -729,7 +729,7 @@ class ClientCallbackReaderFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, + ::grpc_impl::ClientContext* context, const Request* request, ::grpc::experimental::ClientReadReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -866,7 +866,7 @@ class ClientCallbackWriterImpl template ClientCallbackWriterImpl( - Call call, ClientContext* context, Response* response, + Call call, ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) : context_(context), call_(call), @@ -877,7 +877,7 @@ class ClientCallbackWriterImpl finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientWriteReactor* const reactor_; @@ -909,7 +909,7 @@ class ClientCallbackWriterFactory { template static void Create( ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, Response* response, + ::grpc_impl::ClientContext* context, Response* response, ::grpc::experimental::ClientWriteReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); @@ -976,8 +976,8 @@ class ClientCallbackUnaryImpl final friend class ClientCallbackUnaryFactory; template - ClientCallbackUnaryImpl(Call call, ClientContext* context, Request* request, - Response* response, + ClientCallbackUnaryImpl(Call call, ::grpc_impl::ClientContext* context, + Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) : context_(context), call_(call), reactor_(reactor) { this->BindReactor(reactor); @@ -988,7 +988,7 @@ class ClientCallbackUnaryImpl final finish_ops_.AllowNoMessage(); } - ClientContext* const context_; + ::grpc_impl::ClientContext* const context_; Call call_; ::grpc::experimental::ClientUnaryReactor* const reactor_; @@ -1011,8 +1011,8 @@ class ClientCallbackUnaryFactory { template static void Create(ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ClientContext* context, const Request* request, - Response* response, + ::grpc_impl::ClientContext* context, + const Request* request, Response* response, ::grpc::experimental::ClientUnaryReactor* reactor) { Call call = channel->CreateCall(method, context, channel->CallbackCQ()); diff --git a/include/grpcpp/impl/codegen/intercepted_channel.h b/include/grpcpp/impl/codegen/intercepted_channel.h index cd0fcc06753..bcdd89db741 100644 --- a/include/grpcpp/impl/codegen/intercepted_channel.h +++ b/include/grpcpp/impl/codegen/intercepted_channel.h @@ -49,7 +49,7 @@ class InterceptedChannel : public ChannelInterface { InterceptedChannel(ChannelInterface* channel, size_t pos) : channel_(channel), interceptor_pos_(pos) {} - Call CreateCall(const RpcMethod& method, ClientContext* context, + Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq) override { return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); } diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 9600e5f053d..a375d3c0b4c 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace grpc_impl { @@ -34,7 +34,6 @@ class Channel; class CompletionQueue; class ServerCompletionQueue; class ServerCredentials; -class ServerContext; } // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/server_context_impl.h b/include/grpcpp/server_context_impl.h new file mode 100644 index 00000000000..3a944f3da8f --- /dev/null +++ b/include/grpcpp/server_context_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SERVER_CONTEXT_IMPL_H +#define GRPCPP_SERVER_CONTEXT_IMPL_H + +#include + +#endif // GRPCPP_SERVER_CONTEXT_IMPL_H diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index b75012e5da8..f92c80ef97d 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 183ab0dff53..fe242437921 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -930,6 +930,7 @@ include/grpcpp/channel.h \ include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ +include/grpcpp/completion_queue_impl.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ @@ -1019,6 +1020,7 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e2d753e02eb..e500b317af8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -931,6 +931,7 @@ include/grpcpp/channel.h \ include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ +include/grpcpp/completion_queue_impl.h \ include/grpcpp/create_channel.h \ include/grpcpp/create_channel_impl.h \ include/grpcpp/create_channel_posix.h \ @@ -1021,6 +1022,7 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8765f216dab..98b9bdc4261 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10381,6 +10381,7 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -10420,6 +10421,7 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", @@ -10508,6 +10510,7 @@ "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", + "include/grpcpp/completion_queue_impl.h", "include/grpcpp/create_channel.h", "include/grpcpp/create_channel_impl.h", "include/grpcpp/create_channel_posix.h", @@ -10547,6 +10550,7 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", From 650c0216c31c9e8430472891f1b2ce2beaeea32f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 24 Jun 2019 18:30:56 +0200 Subject: [PATCH 455/676] Make sure Grpc metapackage includes Grpc.Core.targets --- src/csharp/Grpc/Grpc.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index b71cd93ff9a..ff6f0d84ef7 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -21,6 +21,7 @@ - + + From 1ce6d98fb4586e3110f5f3039cca16127c9aa030 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 24 Jun 2019 18:33:18 +0200 Subject: [PATCH 456/676] formatting --- src/csharp/Grpc/Grpc.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index ff6f0d84ef7..4cf52cc39f7 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -21,7 +21,7 @@ - + From bb7829b87b31fcb428e92abc07230870bbed5b68 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 24 Jun 2019 12:53:40 -0700 Subject: [PATCH 457/676] Relocate cpu_cost to correct test case --- tools/run_tests/sanity/sanity_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index 065be90108c..1c5dc5d4312 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -23,6 +23,6 @@ - script: tools/distrib/pylint_code.sh - script: tools/distrib/yapf_code.sh - script: tools/distrib/python/check_grpcio_tools.py + cpu_cost: 1000 - script: tools/distrib/check_shadow_boringssl_symbol_list.sh - script: tools/distrib/check_protobuf_pod_version.sh - cpu_cost: 1000 From d61e37111d914eda867b455c94ebedf21b9e7612 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 24 Jun 2019 14:58:30 -0700 Subject: [PATCH 458/676] Disable the backup poller in the client channel when using the background poller. Also, add the missing implementations of grpc_iomgr_run_in_background() for cfstream and libuv. --- src/core/ext/filters/client_channel/backup_poller.cc | 9 +++++---- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 4 ++++ src/core/lib/iomgr/iomgr_uv.cc | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 9e51a83415e..06a241aa8c6 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -16,18 +16,19 @@ * */ -#include - #include "src/core/ext/filters/client_channel/backup_poller.h" #include #include #include +#include #include + #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/surface/channel.h" @@ -153,7 +154,7 @@ static void g_poller_init_locked() { void grpc_client_channel_start_backup_polling( grpc_pollset_set* interested_parties) { - if (g_poll_interval_ms == 0) { + if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) { return; } gpr_mu_lock(&g_poller_mu); @@ -171,7 +172,7 @@ void grpc_client_channel_start_backup_polling( void grpc_client_channel_stop_backup_polling( grpc_pollset_set* interested_parties) { - if (g_poll_interval_ms == 0) { + if (g_poll_interval_ms == 0 || grpc_iomgr_run_in_background()) { return; } grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset); diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index cf4d05318ea..ac9a4497f77 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -90,4 +90,8 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { + return grpc_event_engine_run_in_background(); +} + #endif /* GRPC_CFSTREAM_IOMGR */ diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc index 4a984446dba..d00bfa4d46e 100644 --- a/src/core/lib/iomgr/iomgr_uv.cc +++ b/src/core/lib/iomgr/iomgr_uv.cc @@ -37,4 +37,6 @@ void grpc_set_default_iomgr_platform() { grpc_custom_iomgr_init(&grpc_uv_socket_vtable, &uv_resolver_vtable, &uv_timer_vtable, &uv_pollset_vtable); } + +bool grpc_iomgr_run_in_background() { return false; } #endif From 12c296b3dcf46548dbf3e4d3b4251ee08c9e538e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 24 Jun 2019 16:39:51 -0700 Subject: [PATCH 459/676] [Python] Add authentication extension example --- examples/python/auth/BUILD.bazel | 65 ++++++++++ examples/python/auth/README.md | 48 ++++++++ examples/python/auth/_credentials.py | 31 +++++ .../python/auth/credentials/localhost.crt | 19 +++ .../python/auth/credentials/localhost.key | 27 ++++ examples/python/auth/credentials/root.crt | 20 +++ examples/python/auth/customize_auth_client.py | 111 +++++++++++++++++ examples/python/auth/customize_auth_server.py | 115 ++++++++++++++++++ .../python/auth/test/_auth_example_test.py | 55 +++++++++ 9 files changed, 491 insertions(+) create mode 100644 examples/python/auth/BUILD.bazel create mode 100644 examples/python/auth/README.md create mode 100644 examples/python/auth/_credentials.py create mode 100644 examples/python/auth/credentials/localhost.crt create mode 100644 examples/python/auth/credentials/localhost.key create mode 100644 examples/python/auth/credentials/root.crt create mode 100644 examples/python/auth/customize_auth_client.py create mode 100644 examples/python/auth/customize_auth_server.py create mode 100644 examples/python/auth/test/_auth_example_test.py diff --git a/examples/python/auth/BUILD.bazel b/examples/python/auth/BUILD.bazel new file mode 100644 index 00000000000..6e748d55abe --- /dev/null +++ b/examples/python/auth/BUILD.bazel @@ -0,0 +1,65 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +filegroup( + name = "_credentails_files", + testonly = 1, + srcs = [ + "credentials/localhost.key", + "credentials/localhost.crt", + "credentials/root.crt", + ], +) + +py_library( + name = "_credentials", + testonly = 1, + srcs = ["_credentials.py"], + data = [":_credentails_files"], +) + +py_binary( + name = "customize_auth_client", + testonly = 1, + srcs = ["customize_auth_client.py"], + deps = [ + ":_credentials", + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ], +) + +py_binary( + name = "customize_auth_server", + testonly = 1, + srcs = ["customize_auth_server.py"], + deps = [ + ":_credentials", + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + + ], +) + +py_test( + name = "_auth_example_test", + srcs = ["test/_auth_example_test.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio", + "//examples:py_helloworld", + ":customize_auth_client", + ":customize_auth_server", + ":_credentials", + ], +) diff --git a/examples/python/auth/README.md b/examples/python/auth/README.md new file mode 100644 index 00000000000..a13f829b68a --- /dev/null +++ b/examples/python/auth/README.md @@ -0,0 +1,48 @@ +# Authentication Extension Example in gRPC Python + +## Check Our Guide First + +For most common usage of authentication in gRPC Python, please see our [Authentication](https://grpc.io/docs/guides/auth/) guide's Python section, it includes: + +1. Server SSL credential setup +2. Client SSL credential setup +3. Authenticate with Google using a JWT +4. Authenticate with Google using an Oauth2 token + +Also, the guide talks about gRPC specific credential types. + +### Channel credentials + +Channel credentials are attached to a `Channel` object, the most common use case are SSL credentials. + +### Call credentials + +Call credentials are attached to a `Call` object (corresponding to an RPC). Under the hood, the call credentials is a function that takes in information of the RPC and modify metadata through callback. + +## About This Example + +This example focuses on extending gRPC authentication mechanism: +1) Customize authentication plugin; +2) Composite client side credentials; +3) Validation through interceptor on server side. + +## AuthMetadataPlugin: Manipulate metadata for each call + +Unlike TLS/SSL based authentication, the authentication extension in gRPC Python lives in a much higher level of abstraction. It relies on the transmit of metadata (HTTP Header) between client and server. gRPC Python provides a way to intercept an RPC and append authentication related metadata through [`AuthMetadataPlugin`](https://grpc.github.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin). + +```Python +class AuthMetadataPlugin: + """A specification for custom authentication.""" + + def __call__(self, context, callback): + """Implements authentication by passing metadata to a callback. + + Implementations of this method must not block. + + Args: + context: An AuthMetadataContext providing information on the RPC that + the plugin is being called to authenticate. + callback: An AuthMetadataPluginCallback to be invoked either + synchronously or asynchronously. + """ +``` diff --git a/examples/python/auth/_credentials.py b/examples/python/auth/_credentials.py new file mode 100644 index 00000000000..45b19959bdd --- /dev/null +++ b/examples/python/auth/_credentials.py @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Loading SSL credentials for gRPC Python authentication example.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import os + + +def _load_credential_from_file(filepath): + real_path = os.path.join(os.path.dirname(__file__), filepath) + with open(real_path, 'r') as f: + return f.read() + + +SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt') +SERVER_CERTIFICATE_KEY = _load_credential_from_file('credentials/localhost.key') +ROOT_CERTIFICATE = _load_credential_from_file('credentials/root.crt') diff --git a/examples/python/auth/credentials/localhost.crt b/examples/python/auth/credentials/localhost.crt new file mode 100644 index 00000000000..fc54fd492e1 --- /dev/null +++ b/examples/python/auth/credentials/localhost.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFjCCAf4CCQCzrLIhrWa55zANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJV +UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0wCwYDVQQL +DARnUlBDMCAXDTE5MDYyNDIyMjIzM1oYDzIxMTkwNTMxMjIyMjMzWjBWMQswCQYD +VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEPMA0GA1UECgwGR29vZ2xlMQ0w +CwYDVQQLDARnUlBDMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCtCW0TjugnIUu8BEVIYvdMP+/2GENQDjZhZ8eKR5C6 +toDGbgjsDtt/GxISAg4cg70fIvy0XolnGPZodvfHDM4lJ7yHBOdZD8TXQoE6okR7 +HZuLUJ20M0pXgWqtRewKRUjuYsSDXBnzLiZw1dcv9nGpo+Bqa8NonpiGRRpEkshF +D6T9KU9Ts/x+wMQBIra2Gj0UMh79jPhUuxcYAQA0JQGivnOtdwuPiumpnUT8j8h6 +tWg5l01EsCZWJecCF85KnGpJEVYPyPqBqGsy0nGS9plGotOWF87+jyUQt+KD63xA +aBmTro86mKDDKEK4JvzjVeMGz2UbVcLPiiZnErTFaiXJAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAKsDgOPCWp5WCy17vJbRlgfgk05sVNIHZtzrmdswjBmvSg8MUpep +XqcPNUpsljAXsf9UM5IFEMRdilUsFGWvHjBEtNAW8WUK9UV18WRuU//0w1Mp5HAN +xUEKb4BoyZr65vlCnTR+AR5c9FfPvLibhr5qHs2RA8Y3GyLOcGqBWed87jhdQLCc +P1bxB+96le5JeXq0tw215lxonI2/3ZYVK4/ok9gwXrQoWm8YieJqitk/ZQ4S17/4 +pynHtDfdxLn23EXeGx+UTxJGfpRmhEZdJ+MN7QGYoomzx5qS5XoYKxRNrDlirJpr +OqXIn8E1it+6d5gOZfuHawcNGhRLplE/pfA= +-----END CERTIFICATE----- diff --git a/examples/python/auth/credentials/localhost.key b/examples/python/auth/credentials/localhost.key new file mode 100644 index 00000000000..72e24632828 --- /dev/null +++ b/examples/python/auth/credentials/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEArQltE47oJyFLvARFSGL3TD/v9hhDUA42YWfHikeQuraAxm4I +7A7bfxsSEgIOHIO9HyL8tF6JZxj2aHb3xwzOJSe8hwTnWQ/E10KBOqJEex2bi1Cd +tDNKV4FqrUXsCkVI7mLEg1wZ8y4mcNXXL/ZxqaPgamvDaJ6YhkUaRJLIRQ+k/SlP +U7P8fsDEASK2tho9FDIe/Yz4VLsXGAEANCUBor5zrXcLj4rpqZ1E/I/IerVoOZdN +RLAmViXnAhfOSpxqSRFWD8j6gahrMtJxkvaZRqLTlhfO/o8lELfig+t8QGgZk66P +OpigwyhCuCb841XjBs9lG1XCz4omZxK0xWolyQIDAQABAoIBADeq/Kh6JT3RfGf0 +h8WN8TlaqHxnueAbcmtL0+oss+cdp7gu1jf7X6o4r0uT1a5ew40s2Fe+wj2kzkE1 +ZOlouTlC22gkr7j7Vbxa7PBMG/Pvxoa/XL0IczZLsGImSJXVTG1E4SvRiZeulTdf +1GbdxhtpWV1jZe5Wd4Na3+SHxF5S7m3PrHiZlYdz1ND+8XZs1NlL9+ej72qSFul9 +t/QjMWJ9pky/Wad5abnRLRyOsg+BsgnXbkUy2rD89ZxFMLda9pzXo3TPyAlBHonr +mkEsE4eRMWMpjBM79JbeyDdHn/cs/LjAZrzeDf7ugXr2CHQpKaM5O0PsNHezJII9 +L5kCfzECgYEA4M/rz1UP1/BJoSqigUlSs0tPAg8a5UlkVsh6Osuq72IPNo8qg/Fw +oV/IiIS+q+obRcFj1Od3PGdTpCJwW5dzd2fXBQGmGdj0HucnCrs13RtBh91JiF5i +y/YYI9KfgOG2ZT9gG68T0gTs6jRrS3Qd83npqjrkJqMOd7s00MK9tUcCgYEAxQq7 +T541oCYHSBRIIb0IrR25krZy9caxzCqPDwOcuuhaCqCiaq+ATvOWlSfgecm4eH0K +PCH0xlWxG0auPEwm4pA8+/WR/XJwscPZMuoht1EoKy1his4eKx/s7hHNeO6KOF0V +Y/zqIiuZnEwUoKbn7EqqNFSTT65PJKyGsICJFG8CgYAfaw9yl1myfQNdQb8aQGwN +YJ33FLNWje427qeeZe5KrDKiFloDvI9YDjHRWnPnRL1w/zj7fSm9yFb5HlMDieP6 +MQnsyjEzdY2QcA+VwVoiv3dmDHgFVeOKy6bOAtaFxYWfGr9MvygO9t9BT/gawGyb +JVORlc9i0vDnrMMR1dV7awKBgBpTWLtGc/u1mPt0Wj7HtsUKV6TWY32a0l5owTxM +S0BdksogtBJ06DukJ9Y9wawD23WdnyRxlPZ6tHLkeprrwbY7dypioOKvy4a0l+xJ +g7+uRCOgqIuXBkjUtx8HmeAyXp0xMo5tWArAsIFFWOwt4IadYygitJvMuh44PraO +NcJZAoGADEiV0dheXUCVr8DrtSom8DQMj92/G/FIYjXL8OUhh0+F+YlYP0+F8PEU +yYIWEqL/S5tVKYshimUXQa537JcRKsTVJBG/ZKD2kuqgOc72zQy3oplimXeJDCXY +h2eAQ0u8GN6tN9C4t8Kp4a3y6FGsxgu+UTxdnL3YQ+yHAVhtCzo= +-----END RSA PRIVATE KEY----- diff --git a/examples/python/auth/credentials/root.crt b/examples/python/auth/credentials/root.crt new file mode 100644 index 00000000000..0fa644d3e59 --- /dev/null +++ b/examples/python/auth/credentials/root.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWTCCAkGgAwIBAgIJAPOConZMwykwMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29nbGUxDTAL +BgNVBAsMBGdSUEMwIBcNMTkwNjI0MjIyMDA3WhgPMjExOTA1MzEyMjIwMDdaMEIx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMQ8wDQYDVQQKDAZHb29n +bGUxDTALBgNVBAsMBGdSUEMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwqei3TfyLidnQNDJ2lierMYo229K92DuORni7nSjJQ59Jc3dNMsmqGQJjCD8o +6mTlKM/oCbs27Wpx+OxcOLvT95j2kiDGca1fCvaMdguIod09SWiyMpv/hp0trLv7 +NJIKHznath6rHYX2Ii3fZ1yCPzyQbEPSAA+GNpoNm1v1ZWmWKke9v7vLlS3inNlW +Mt9jepK7DrtbNZnVDjeItnppBSbVYRMxIyNHkepFbqXx5TpkCvl4M4XQZw9bfSxQ +i3WZ3q+T1Tw//OUdPNc+OfMhu0MA0QoMwikskP0NaIC3dbJZ5Ogx0RcnaB4E+9C6 +O/znUEh3WuKVl5HXBF+UwWoFAgMBAAGjUDBOMB0GA1UdDgQWBBRm3JIgzgK4G97J +fbMGatWMZc7V3jAfBgNVHSMEGDAWgBRm3JIgzgK4G97JfbMGatWMZc7V3jAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCNiV8x41if094ry2srS0YucpiN +3rTPk08FOLsENTMYai524TGXJti1P6ofGr5KXCL0uxTByHE3fEiMMud2TIY5iHQo +Y4mzDTTcb+Q7yKHwYZMlcp6nO8W+NeY5t+S0JPHhb8deKWepcN2UpXBUYQLw7AiE +l96T9Gi+vC9h/XE5IVwHFQXTxf5UYzXtW1nfapvrOONg/ms41dgmrRKIi+knWfiJ +FdHpHX2sfDAoJtnpEISX+nxRGNVTLY64utXWm4yxaZJshvy2s8zWJgRg7rtwAhTT +Np9E9MnihXLEmDI4Co9XlLPJyZFmqImsbmVuKFeQOCiLAoPJaMI2lbi7fiTo +-----END CERTIFICATE----- diff --git a/examples/python/auth/customize_auth_client.py b/examples/python/auth/customize_auth_client.py new file mode 100644 index 00000000000..324f629caf1 --- /dev/null +++ b/examples/python/auth/customize_auth_client.py @@ -0,0 +1,111 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Client of the Python example of customizing authentication mechanism.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import contextlib +import logging +import os + +import grpc +from examples import helloworld_pb2, helloworld_pb2_grpc +from examples.python.auth import _credentials + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + +_SERVER_ADDR_TEMPLATE = 'localhost:%d' +_SIGNATURE_HEADER_KEY = 'x-signautre' + + +class AuthGateway(grpc.AuthMetadataPlugin): + + def __call__(self, context, callback): + """Implements authentication by passing metadata to a callback. + + Implementations of this method must not block. + + Args: + context: An AuthMetadataContext providing information on the RPC that + the plugin is being called to authenticate. + callback: An AuthMetadataPluginCallback to be invoked either + synchronously or asynchronously. + """ + # Example AuthMetadataContext object: + # AuthMetadataContext( + # service_url=u'https://localhost:50051/helloworld.Greeter', + # method_name=u'SayHello') + signature = context.method_name[::-1] + callback(((_SIGNATURE_HEADER_KEY, signature),), None) + + +def _load_credential_from_file(filepath): + real_path = os.path.join(os.path.dirname(__file__), filepath) + with open(real_path, 'r') as f: + return f.read() + + +@contextlib.contextmanager +def create_client_channel(addr): + # Call credential object will be invoked for every single RPC + call_credentials = grpc.metadata_call_credentials( + AuthGateway(), name='auth gateway') + # Channel credential will be valid for the entire channel + channel_credential = grpc.ssl_channel_credentials( + _credentials.ROOT_CERTIFICATE) + # Combining channel credentials and call credentials together + composite_credentials = grpc.composite_channel_credentials( + channel_credential, + call_credentials, + ) + channel = grpc.secure_channel(addr, composite_credentials) + yield channel + + +def send_rpc(channel): + stub = helloworld_pb2_grpc.GreeterStub(channel) + request = helloworld_pb2.HelloRequest(name='you') + try: + response = stub.SayHello(request) + except grpc.RpcError as rpc_error: + _LOGGER.error('Received error: %s', rpc_error) + return rpc_error + else: + _LOGGER.info('Received message: %s', response) + return response + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--port', + nargs=1, + type=int, + default=50051, + help='the address of server') + args = parser.parse_args() + + with create_client_channel(_SERVER_ADDR_TEMPLATE % args.port) as channel: + send_rpc(channel) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + main() diff --git a/examples/python/auth/customize_auth_server.py b/examples/python/auth/customize_auth_server.py new file mode 100644 index 00000000000..23805ae7c3e --- /dev/null +++ b/examples/python/auth/customize_auth_server.py @@ -0,0 +1,115 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Server of the Python example of customizing authentication mechanism.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import contextlib +import logging +import os +import time +from concurrent import futures + +import grpc +from examples import helloworld_pb2, helloworld_pb2_grpc +from examples.python.auth import _credentials + +_LOGGER = logging.getLogger(__name__) +_LOGGER.setLevel(logging.INFO) + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + +_LISTEN_ADDRESS_TEMPLATE = 'localhost:%d' +_SIGNATURE_HEADER_KEY = 'x-signautre' + + +class SignatureValidationInterceptor(grpc.ServerInterceptor): + + def __init__(self): + + def abort(ignored_request, context): + context.abort(grpc.StatusCode.UNAUTHENTICATED, 'Invalid signature') + + self._abortion = grpc.unary_unary_rpc_method_handler(abort) + + def intercept_service(self, continuation, handler_call_details): + # Example HandlerCallDetails object: + # _HandlerCallDetails( + # method=u'/helloworld.Greeter/SayHello', + # invocation_metadata=...) + method_name = handler_call_details.method.split('/')[-1] + expected_metadata = (_SIGNATURE_HEADER_KEY, method_name[::-1]) + if expected_metadata in handler_call_details.invocation_metadata: + return continuation(handler_call_details) + else: + return self._abortion + + +class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer): + + @staticmethod + def SayHello(request, unused_context): + return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) + + +def _load_credential_from_file(filepath): + real_path = os.path.join(os.path.dirname(__file__), filepath) + with open(real_path, 'r') as f: + return f.read() + + +@contextlib.contextmanager +def run_server(port): + # Bind interceptor to server + server = grpc.server( + futures.ThreadPoolExecutor(), + interceptors=(SignatureValidationInterceptor(),)) + helloworld_pb2_grpc.add_GreeterServicer_to_server(SimpleGreeter(), server) + + # Loading credentials + server_credentials = grpc.ssl_server_credentials((( + _credentials.SERVER_CERTIFICATE_KEY, + _credentials.SERVER_CERTIFICATE, + ),)) + + # Pass down credentails + port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port, + server_credentials) + + server.start() + yield port + server.stop(0) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--port', nargs=1, type=int, default=50051, help='the listening port') + args = parser.parse_args() + + with run_server(args.port) as port: + logging.info('Server is listening at port :%d', port) + try: + while True: + time.sleep(_ONE_DAY_IN_SECONDS) + except KeyboardInterrupt: + pass + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + main() diff --git a/examples/python/auth/test/_auth_example_test.py b/examples/python/auth/test/_auth_example_test.py new file mode 100644 index 00000000000..5659a1bf887 --- /dev/null +++ b/examples/python/auth/test/_auth_example_test.py @@ -0,0 +1,55 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test for gRPC Python authentication example.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import unittest + +import grpc +from examples.python.auth import (_credentials, customize_auth_client, + customize_auth_server) + +_SERVER_ADDR_TEMPLATE = 'localhost:%d' + + +class AuthExampleTest(unittest.TestCase): + + def test_successful_call(self): + with customize_auth_server.run_server(0) as port: + with customize_auth_client.create_client_channel( + _SERVER_ADDR_TEMPLATE % port) as channel: + customize_auth_client.send_rpc(channel) + # No unhandled exception raised, test passed! + + def test_no_channel_credential(self): + with customize_auth_server.run_server(0) as port: + with grpc.insecure_channel(_SERVER_ADDR_TEMPLATE % port) as channel: + resp = customize_auth_client.send_rpc(channel) + self.assertEqual(resp.code(), grpc.StatusCode.UNAVAILABLE) + + def test_no_call_credential(self): + with customize_auth_server.run_server(0) as port: + channel_credential = grpc.ssl_channel_credentials( + _credentials.ROOT_CERTIFICATE) + with grpc.secure_channel(_SERVER_ADDR_TEMPLATE % port, + channel_credential) as channel: + resp = customize_auth_client.send_rpc(channel) + self.assertEqual(resp.code(), grpc.StatusCode.UNAUTHENTICATED) + + +if __name__ == '__main__': + unittest.main(verbosity=2) From 5f98b1e8efa76fe7670d7cd3cb5b1b86772578cf Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 24 Jun 2019 17:13:42 -0700 Subject: [PATCH 460/676] Fix 2/3 str/bytes compatibility issue --- examples/python/auth/_credentials.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/auth/_credentials.py b/examples/python/auth/_credentials.py index 45b19959bdd..39939f6284b 100644 --- a/examples/python/auth/_credentials.py +++ b/examples/python/auth/_credentials.py @@ -23,7 +23,7 @@ import os def _load_credential_from_file(filepath): real_path = os.path.join(os.path.dirname(__file__), filepath) with open(real_path, 'r') as f: - return f.read() + return bytes(f.read()) SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt') From aa567e5364958862561a3815eaa41a2655aba8b4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 24 Jun 2019 17:58:11 -0700 Subject: [PATCH 461/676] Adopt reviewer's advices --- examples/python/auth/BUILD.bazel | 16 ++--- examples/python/auth/README.md | 72 +++++++++++++++++-- ...th_client.py => customized_auth_client.py} | 4 +- ...th_server.py => customized_auth_server.py} | 15 ++-- 4 files changed, 86 insertions(+), 21 deletions(-) rename examples/python/auth/{customize_auth_client.py => customized_auth_client.py} (98%) rename examples/python/auth/{customize_auth_server.py => customized_auth_server.py} (92%) diff --git a/examples/python/auth/BUILD.bazel b/examples/python/auth/BUILD.bazel index 6e748d55abe..7bb4203f93f 100644 --- a/examples/python/auth/BUILD.bazel +++ b/examples/python/auth/BUILD.bazel @@ -13,7 +13,7 @@ # limitations under the License. filegroup( - name = "_credentails_files", + name = "_credentials_files", testonly = 1, srcs = [ "credentials/localhost.key", @@ -26,13 +26,13 @@ py_library( name = "_credentials", testonly = 1, srcs = ["_credentials.py"], - data = [":_credentails_files"], + data = [":_credentials_files"], ) py_binary( - name = "customize_auth_client", + name = "customized_auth_client", testonly = 1, - srcs = ["customize_auth_client.py"], + srcs = ["customized_auth_client.py"], deps = [ ":_credentials", "//src/python/grpcio/grpc:grpcio", @@ -41,9 +41,9 @@ py_binary( ) py_binary( - name = "customize_auth_server", + name = "customized_auth_server", testonly = 1, - srcs = ["customize_auth_server.py"], + srcs = ["customized_auth_server.py"], deps = [ ":_credentials", "//src/python/grpcio/grpc:grpcio", @@ -58,8 +58,8 @@ py_test( deps = [ "//src/python/grpcio/grpc:grpcio", "//examples:py_helloworld", - ":customize_auth_client", - ":customize_auth_server", + ":customized_auth_client", + ":customized_auth_server", ":_credentials", ], ) diff --git a/examples/python/auth/README.md b/examples/python/auth/README.md index a13f829b68a..2fd044b8a30 100644 --- a/examples/python/auth/README.md +++ b/examples/python/auth/README.md @@ -2,7 +2,9 @@ ## Check Our Guide First -For most common usage of authentication in gRPC Python, please see our [Authentication](https://grpc.io/docs/guides/auth/) guide's Python section, it includes: +For most common usage of authentication in gRPC Python, please see our +[Authentication](https://grpc.io/docs/guides/auth/) guide's Python section. The +Guide includes following scenarios: 1. Server SSL credential setup 2. Client SSL credential setup @@ -13,11 +15,14 @@ Also, the guide talks about gRPC specific credential types. ### Channel credentials -Channel credentials are attached to a `Channel` object, the most common use case are SSL credentials. +Channel credentials are attached to a `Channel` object, the most common use case +are SSL credentials. ### Call credentials -Call credentials are attached to a `Call` object (corresponding to an RPC). Under the hood, the call credentials is a function that takes in information of the RPC and modify metadata through callback. +Call credentials are attached to a `Call` object (corresponding to an RPC). +Under the hood, the call credentials is a function that takes in information of +the RPC and modify metadata through callback. ## About This Example @@ -28,7 +33,16 @@ This example focuses on extending gRPC authentication mechanism: ## AuthMetadataPlugin: Manipulate metadata for each call -Unlike TLS/SSL based authentication, the authentication extension in gRPC Python lives in a much higher level of abstraction. It relies on the transmit of metadata (HTTP Header) between client and server. gRPC Python provides a way to intercept an RPC and append authentication related metadata through [`AuthMetadataPlugin`](https://grpc.github.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin). +Unlike TLS/SSL based authentication, the authentication extension in gRPC Python +lives at a much higher level of networking. It relies on the transmission of +metadata (HTTP Header) between client and server, instead of alternating the +transport protocol. + +gRPC Python provides a way to intercept an RPC and append authentication related +metadata through +[`AuthMetadataPlugin`](https://grpc.github.io/grpc/python/grpc.html#grpc.AuthMetadataPlugin). +Those in need of a custom authentication method may simply provide a concrete +implementation of the following interface: ```Python class AuthMetadataPlugin: @@ -46,3 +60,53 @@ class AuthMetadataPlugin: synchronously or asynchronously. """ ``` + +Then pass the instance of the concrete implementation to +`grpc.metadata_call_credentials` function to be converted into a +`CallCredentials` object. Please NOTE that it is possible to pass a Python +function object directly, but we recommend to inherit from the base class to +ensure implementation correctness. + + +```Python +def metadata_call_credentials(metadata_plugin, name=None): + """Construct CallCredentials from an AuthMetadataPlugin. + + Args: + metadata_plugin: An AuthMetadataPlugin to use for authentication. + name: An optional name for the plugin. + + Returns: + A CallCredentials. + """ +``` + +The `CallCredentials` object can be passed directly into an RPC like: + +```Python +call_credentials = grpc.metadata_call_credentials(my_foo_plugin) +stub.FooRpc(request, credentials=call_credentials) +``` + +Or you can use `ChannelCredentials` and `CallCredentials` at the same time by +combining them: + +```Python +channel_credentials = ... +call_credentials = ... +composite_credentials = grpc.composite_channel_credentials( + channel_credential, + call_credentials) +channel = grpc.secure_channel(server_address, composite_credentials) +``` + +It is also possible to apply multiple `CallCredentials` to a single RPC: + +```Python +call_credentials_foo = ... +call_credentials_bar = ... +call_credentials = grpc.composite_call_credentials( + call_credentials_foo, + call_credentials_bar) +stub.FooRpc(request, credentials=call_credentials) +``` diff --git a/examples/python/auth/customize_auth_client.py b/examples/python/auth/customized_auth_client.py similarity index 98% rename from examples/python/auth/customize_auth_client.py rename to examples/python/auth/customized_auth_client.py index 324f629caf1..c9ba7c70074 100644 --- a/examples/python/auth/customize_auth_client.py +++ b/examples/python/auth/customized_auth_client.py @@ -32,7 +32,7 @@ _LOGGER.setLevel(logging.INFO) _ONE_DAY_IN_SECONDS = 60 * 60 * 24 _SERVER_ADDR_TEMPLATE = 'localhost:%d' -_SIGNATURE_HEADER_KEY = 'x-signautre' +_SIGNATURE_HEADER_KEY = 'x-signature' class AuthGateway(grpc.AuthMetadataPlugin): @@ -96,7 +96,7 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument( '--port', - nargs=1, + nargs='?', type=int, default=50051, help='the address of server') diff --git a/examples/python/auth/customize_auth_server.py b/examples/python/auth/customized_auth_server.py similarity index 92% rename from examples/python/auth/customize_auth_server.py rename to examples/python/auth/customized_auth_server.py index 23805ae7c3e..915c74a7510 100644 --- a/examples/python/auth/customize_auth_server.py +++ b/examples/python/auth/customized_auth_server.py @@ -34,7 +34,7 @@ _LOGGER.setLevel(logging.INFO) _ONE_DAY_IN_SECONDS = 60 * 60 * 24 _LISTEN_ADDRESS_TEMPLATE = 'localhost:%d' -_SIGNATURE_HEADER_KEY = 'x-signautre' +_SIGNATURE_HEADER_KEY = 'x-signature' class SignatureValidationInterceptor(grpc.ServerInterceptor): @@ -61,8 +61,7 @@ class SignatureValidationInterceptor(grpc.ServerInterceptor): class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer): - @staticmethod - def SayHello(request, unused_context): + def SayHello(self, request, unused_context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) @@ -86,19 +85,21 @@ def run_server(port): _credentials.SERVER_CERTIFICATE, ),)) - # Pass down credentails + # Pass down credentials port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port, server_credentials) server.start() - yield port - server.stop(0) + try: + yield port + finally: + server.stop(0) def main(): parser = argparse.ArgumentParser() parser.add_argument( - '--port', nargs=1, type=int, default=50051, help='the listening port') + '--port', nargs='?', type=int, default=50051, help='the listening port') args = parser.parse_args() with run_server(args.port) as port: From 8f30132877c97ec79aa0f087ad4aece9c37ef35e Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 24 Jun 2019 21:15:01 -0700 Subject: [PATCH 462/676] Revert the previous clang-format changes to pass the clang format check on github. --- src/core/ext/filters/client_channel/backup_poller.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 06a241aa8c6..2e2d8d607de 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -16,12 +16,13 @@ * */ +#include + #include "src/core/ext/filters/client_channel/backup_poller.h" #include #include #include -#include #include #include "src/core/ext/filters/client_channel/client_channel.h" From 7b8292406656e4a53b073153a50283bdeb5b1c5e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 24 Jun 2019 19:53:41 -0700 Subject: [PATCH 463/676] Update module import according to name changes --- .../python/auth/customized_auth_client.py | 3 ++- .../python/auth/customized_auth_server.py | 3 ++- .../python/auth/test/_auth_example_test.py | 19 ++++++++++--------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/python/auth/customized_auth_client.py b/examples/python/auth/customized_auth_client.py index c9ba7c70074..4ec0c2d3806 100644 --- a/examples/python/auth/customized_auth_client.py +++ b/examples/python/auth/customized_auth_client.py @@ -23,7 +23,8 @@ import logging import os import grpc -from examples import helloworld_pb2, helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc from examples.python.auth import _credentials _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/auth/customized_auth_server.py b/examples/python/auth/customized_auth_server.py index 915c74a7510..f79c2639d90 100644 --- a/examples/python/auth/customized_auth_server.py +++ b/examples/python/auth/customized_auth_server.py @@ -25,7 +25,8 @@ import time from concurrent import futures import grpc -from examples import helloworld_pb2, helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc from examples.python.auth import _credentials _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/auth/test/_auth_example_test.py b/examples/python/auth/test/_auth_example_test.py index 5659a1bf887..e2214267212 100644 --- a/examples/python/auth/test/_auth_example_test.py +++ b/examples/python/auth/test/_auth_example_test.py @@ -20,8 +20,9 @@ from __future__ import print_function import unittest import grpc -from examples.python.auth import (_credentials, customize_auth_client, - customize_auth_server) +from examples.python.auth import _credentials +from examples.python.auth import customized_auth_client +from examples.python.auth import customized_auth_server _SERVER_ADDR_TEMPLATE = 'localhost:%d' @@ -29,25 +30,25 @@ _SERVER_ADDR_TEMPLATE = 'localhost:%d' class AuthExampleTest(unittest.TestCase): def test_successful_call(self): - with customize_auth_server.run_server(0) as port: - with customize_auth_client.create_client_channel( + with customized_auth_server.run_server(0) as port: + with customized_auth_client.create_client_channel( _SERVER_ADDR_TEMPLATE % port) as channel: - customize_auth_client.send_rpc(channel) + customized_auth_client.send_rpc(channel) # No unhandled exception raised, test passed! def test_no_channel_credential(self): - with customize_auth_server.run_server(0) as port: + with customized_auth_server.run_server(0) as port: with grpc.insecure_channel(_SERVER_ADDR_TEMPLATE % port) as channel: - resp = customize_auth_client.send_rpc(channel) + resp = customized_auth_client.send_rpc(channel) self.assertEqual(resp.code(), grpc.StatusCode.UNAVAILABLE) def test_no_call_credential(self): - with customize_auth_server.run_server(0) as port: + with customized_auth_server.run_server(0) as port: channel_credential = grpc.ssl_channel_credentials( _credentials.ROOT_CERTIFICATE) with grpc.secure_channel(_SERVER_ADDR_TEMPLATE % port, channel_credential) as channel: - resp = customize_auth_client.send_rpc(channel) + resp = customized_auth_client.send_rpc(channel) self.assertEqual(resp.code(), grpc.StatusCode.UNAUTHENTICATED) From 47871c274ed13b9cad8fe0e61c0a5fee860ed1fd Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 12:47:27 -0700 Subject: [PATCH 464/676] Change channelz SubchannelNode to no longer take a ref to the Subchannel --- .../client_channel/client_channel_channelz.cc | 22 ++++++++++++------- .../client_channel/client_channel_channelz.h | 20 +++++++++++++++-- .../ext/filters/client_channel/subchannel.cc | 9 +++++++- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index e068d11dc41..fb7d1cbbc16 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -30,23 +30,29 @@ namespace grpc_core { namespace channelz { -SubchannelNode::SubchannelNode(Subchannel* subchannel, +SubchannelNode::SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), - subchannel_(subchannel), - target_(UniquePtr(gpr_strdup(subchannel_->GetTargetAddress()))), + subchannel_destroyed_(false), + target_(UniquePtr(gpr_strdup(target_address))), trace_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} +void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) { + connectivity_state_.Store(state, MemoryOrder::RELAXED); +} + +void SubchannelNode::SetChildSocketUuid(intptr_t uuid) { + child_socket_uuid_.Store(uuid, MemoryOrder::RELAXED); +} + void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; - if (subchannel_ == nullptr) { + if (subchannel_destroyed_) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = subchannel_->CheckConnectivityState( - nullptr /* health_check_service_name */, - nullptr /* connected_subchannel */); + state = connectivity_state_.Load(MemoryOrder::RELAXED); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); @@ -87,7 +93,7 @@ grpc_json* SubchannelNode::RenderJson() { call_counter_.PopulateCallCounts(json); json = top_level_json; // populate the child socket. - intptr_t socket_uuid = subchannel_->GetChildSocketUuid(); + intptr_t socket_uuid = child_socket_uuid_.Load(MemoryOrder::RELAXED); if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 9f11e928998..ef50f45f73a 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -34,9 +34,23 @@ namespace channelz { class SubchannelNode : public BaseNode { public: - SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); + SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes); ~SubchannelNode() override; + void MarkSubchannelDestroyed() { + GPR_ASSERT(!subchannel_destroyed_); + subchannel_destroyed_ = true; + } + + // Used when the subchannel's transport connectivity state changes. + void UpdateConnectivityState(grpc_connectivity_state state); + + // Used when the subchannel's child socket uuid changes. This should be set + // when the subchannel's transport is created and set to 0 when the subchannel + // unrefs the transport. A uuid of 0 indicates that the child socket is no + // longer associated with this subchannel. + void SetChildSocketUuid(intptr_t uuid); + void MarkSubchannelDestroyed() { GPR_ASSERT(subchannel_ != nullptr); subchannel_ = nullptr; @@ -61,7 +75,9 @@ class SubchannelNode : public BaseNode { private: void PopulateConnectivityState(grpc_json* json); - Subchannel* subchannel_; + bool subchannel_destroyed_; + Atomic connectivity_state_{GRPC_CHANNEL_IDLE}; + Atomic child_socket_uuid_{0}; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index dd16eded826..069a58bf605 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -344,6 +344,9 @@ class Subchannel::ConnectedSubchannelStateWatcher { self->pending_connectivity_state_)); } c->connected_subchannel_.reset(); + if (c->channelz_node() != nullptr) { + c->channelz_node()->SetChildSocketUuid(0); + } c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); c->backoff_begun_ = false; c->backoff_.Reset(); @@ -676,7 +679,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { channelz_node_ = MakeRefCounted( - this, channel_tracer_max_memory); + this->GetTargetAddress(), channel_tracer_max_memory); channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel created")); @@ -930,6 +933,7 @@ const char* SubchannelConnectivityStateChangeString( void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { state_ = state; if (channelz_node_ != nullptr) { + channelz_node()->UpdateConnectivityState(state); channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string( @@ -1081,6 +1085,9 @@ bool Subchannel::PublishTransportLocked() { New(stk, args_, channelz_node_, socket_uuid)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", connected_subchannel_.get(), this); + if (channelz_node() != nullptr) { + channelz_node()->SetChildSocketUuid(socket_uuid); + } // Instantiate state watcher. Will clean itself up. New(this); // Report initial state. From b7dc50942984cf04eccccf663c839a217100e69d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 12:53:12 -0700 Subject: [PATCH 465/676] Minor fix --- src/core/ext/filters/client_channel/subchannel.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 069a58bf605..68353b897e2 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -933,7 +933,7 @@ const char* SubchannelConnectivityStateChangeString( void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) { state_ = state; if (channelz_node_ != nullptr) { - channelz_node()->UpdateConnectivityState(state); + channelz_node_->UpdateConnectivityState(state); channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string( @@ -1085,8 +1085,8 @@ bool Subchannel::PublishTransportLocked() { New(stk, args_, channelz_node_, socket_uuid)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", connected_subchannel_.get(), this); - if (channelz_node() != nullptr) { - channelz_node()->SetChildSocketUuid(socket_uuid); + if (channelz_node_ != nullptr) { + channelz_node_->SetChildSocketUuid(socket_uuid); } // Instantiate state watcher. Will clean itself up. New(this); From d137ee8a85a9389cb4dca5154939fed60622886a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 12:59:41 -0700 Subject: [PATCH 466/676] Fix format --- src/core/ext/filters/client_channel/subchannel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 68353b897e2..28fe6d87c6d 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -344,7 +344,7 @@ class Subchannel::ConnectedSubchannelStateWatcher { self->pending_connectivity_state_)); } c->connected_subchannel_.reset(); - if (c->channelz_node() != nullptr) { + if (c->channelz_node() != nullptr) { c->channelz_node()->SetChildSocketUuid(0); } c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE); From a240860008889df2365664a0adb5f3f4eb1acc10 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 14:12:28 -0700 Subject: [PATCH 467/676] Minor fix --- .../ext/filters/client_channel/client_channel_channelz.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index ef50f45f73a..34b8e269a2e 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -51,11 +51,6 @@ class SubchannelNode : public BaseNode { // longer associated with this subchannel. void SetChildSocketUuid(intptr_t uuid); - void MarkSubchannelDestroyed() { - GPR_ASSERT(subchannel_ != nullptr); - subchannel_ = nullptr; - } - grpc_json* RenderJson() override; // proxy methods to composed classes. From 3c72a939fce12756a88511e88c092b983ac9649e Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 15:39:16 -0700 Subject: [PATCH 468/676] Remove subchannel_destroyed_ --- .../ext/filters/client_channel/client_channel_channelz.cc | 7 +------ .../ext/filters/client_channel/client_channel_channelz.h | 6 ------ src/core/ext/filters/client_channel/subchannel.cc | 2 +- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index fb7d1cbbc16..f21d45d8c0f 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -33,7 +33,6 @@ namespace channelz { SubchannelNode::SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), - subchannel_destroyed_(false), target_(UniquePtr(gpr_strdup(target_address))), trace_(channel_tracer_max_nodes) {} @@ -49,11 +48,7 @@ void SubchannelNode::SetChildSocketUuid(intptr_t uuid) { void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; - if (subchannel_destroyed_) { - state = GRPC_CHANNEL_SHUTDOWN; - } else { - state = connectivity_state_.Load(MemoryOrder::RELAXED); - } + state = connectivity_state_.Load(MemoryOrder::RELAXED); json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); grpc_json_create_child(nullptr, json, "state", diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 34b8e269a2e..b9eaec7e0c5 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -37,11 +37,6 @@ class SubchannelNode : public BaseNode { SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes); ~SubchannelNode() override; - void MarkSubchannelDestroyed() { - GPR_ASSERT(!subchannel_destroyed_); - subchannel_destroyed_ = true; - } - // Used when the subchannel's transport connectivity state changes. void UpdateConnectivityState(grpc_connectivity_state state); @@ -70,7 +65,6 @@ class SubchannelNode : public BaseNode { private: void PopulateConnectivityState(grpc_json* json); - bool subchannel_destroyed_; Atomic connectivity_state_{GRPC_CHANNEL_IDLE}; Atomic child_socket_uuid_{0}; UniquePtr target_; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 28fe6d87c6d..9a6655e45d6 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -691,7 +691,7 @@ Subchannel::~Subchannel() { channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel destroyed")); - channelz_node_->MarkSubchannelDestroyed(); + channelz_node_->UpdateConnectivityState(GRPC_CHANNEL_SHUTDOWN); } grpc_channel_args_destroy(args_); grpc_connector_unref(connector_); From 44160d2b65e82d82be5a99ffb20583d9c4b12fb8 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 25 Jun 2019 15:43:06 -0700 Subject: [PATCH 469/676] Add unit test to check the re-entrancy of callbacks --- .../end2end/client_callback_end2end_test.cc | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 8cf6def1073..52797672fc0 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -374,6 +374,79 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { SendRpcs(1, false); } +TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { + MAYBE_SKIP_TEST; + ResetStub(); + std::mutex mu1, mu2, mu3; + std::condition_variable cv1, cv2, cv3; + bool done1 = false; + EchoRequest request1, request2, request3; + request1.set_message("Hello locked world1."); + EchoResponse response1; + ClientContext cli_ctx1; + { + std::unique_lock l(mu1); + stub_->experimental_async()->Echo( + &cli_ctx1, &request1, &response1, + [&mu1, this, &cv1, &done1, &request1, &response1](Status s1) { + std::unique_lock l1(mu1); + EXPECT_TRUE(s1.ok()); + EXPECT_EQ(request1.message(), response1.message()); + // start the second level of nesting + std::mutex mu2; + bool done2 = false; + std::condition_variable cv2; + EchoRequest request2; + request2.set_message("Hello locked world2."); + EchoResponse response2; + ClientContext cli_ctx2; + std::unique_lock l2(mu2); + stub_->experimental_async()->Echo( + &cli_ctx2, &request2, &response2, + [&mu2, this, &cv2, &done2, &request2, &response2](Status s2) { + std::unique_lock l2(mu2); + EXPECT_TRUE(s2.ok()); + EXPECT_EQ(request2.message(), response2.message()); + // start the third level of nesting + std::mutex mu3; + bool done3 = false; + std::condition_variable cv3; + EchoRequest request3; + request3.set_message("Hello locked world2."); + EchoResponse response3; + ClientContext cli_ctx3; + std::unique_lock l3(mu3); + stub_->experimental_async()->Echo( + &cli_ctx3, &request3, &response3, + [&mu3, &cv3, &done3, &request3, &response3](Status s3) { + std::lock_guard l(mu3); + EXPECT_TRUE(s3.ok()); + EXPECT_EQ(request3.message(), response3.message()); + done3 = true; + cv3.notify_all(); + }); + done2 = true; + cv2.notify_all(); + // Wait for inner most rpc to return. + while (!done3) { + cv3.wait(l3); + } + }); + // Wait for second rpc to return. + while (!done2) { + cv2.wait(l2); + } + done1 = true; + cv1.notify_all(); + }); + } + + std::unique_lock l1(mu1); + while (!done1) { + cv1.wait(l1); + } +} + TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) { MAYBE_SKIP_TEST; ResetStub(); From a019017840bed8798390fc09758348f1c79b1ae3 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 25 Jun 2019 15:50:10 -0700 Subject: [PATCH 470/676] Address minor comments --- src/core/ext/filters/client_channel/client_channel_channelz.h | 2 +- src/core/ext/filters/client_channel/subchannel.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index b9eaec7e0c5..d5aa20ca9a1 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -37,7 +37,7 @@ class SubchannelNode : public BaseNode { SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes); ~SubchannelNode() override; - // Used when the subchannel's transport connectivity state changes. + // Used when the subchannel's connectivity state changes. void UpdateConnectivityState(grpc_connectivity_state state); // Used when the subchannel's child socket uuid changes. This should be set diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 9a6655e45d6..8ed821e236e 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -679,7 +679,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { channelz_node_ = MakeRefCounted( - this->GetTargetAddress(), channel_tracer_max_memory); + GetTargetAddress(), channel_tracer_max_memory); channelz_node_->AddTraceEvent( channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel created")); From 5955baf3d916a85ea9ee219ea245dadbd265cbcd Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 25 Jun 2019 19:37:02 -0700 Subject: [PATCH 471/676] Change comment words --- src/core/lib/iomgr/executor/mpmcqueue.cc | 8 +++----- src/core/lib/iomgr/executor/mpmcqueue.h | 10 +++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index cf8ade721d3..2bc3ffbc392 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -22,10 +22,10 @@ namespace grpc_core { -DebugOnlyTraceFlag thread_pool(false, "thread_pool_trace"); +DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool_trace"); inline void* InfLenFIFOQueue::PopFront() { - // Caller should already checked queue is not empty and has already hold the + // Caller should already check queue is not empty and has already held the // mutex. This function will only do the job of removal. void* result = queue_head_->content; Node* head_to_remove = queue_head_; @@ -33,7 +33,7 @@ inline void* InfLenFIFOQueue::PopFront() { count_.FetchSub(1, MemoryOrder::RELAXED); - if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { gpr_timespec wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), head_to_remove->insert_time); @@ -67,8 +67,6 @@ inline void* InfLenFIFOQueue::PopFront() { return result; } -InfLenFIFOQueue::InfLenFIFOQueue() {} - InfLenFIFOQueue::~InfLenFIFOQueue() { GPR_ASSERT(count_.Load(MemoryOrder::RELAXED) == 0); GPR_ASSERT(num_waiters_ == 0); diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 964ac6a8b41..8ece95699c7 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -28,7 +28,7 @@ namespace grpc_core { -extern DebugOnlyTraceFlag thread_pool; +extern DebugOnlyTraceFlag grpc_thread_pool_trace; // Abstract base class of a Multiple-Producer-Multiple-Consumer(MPMC) queue // interface @@ -53,10 +53,10 @@ class MPMCQueueInterface { class InfLenFIFOQueue : public MPMCQueueInterface { public: // Creates a new MPMC Queue. The queue created will have infinite length. - InfLenFIFOQueue(); + InfLenFIFOQueue() {} - // Releases all resources hold by the queue. The queue must be empty, and no - // one waiting on conditional variables. + // Releases all resources held by the queue. The queue must be empty, and no + // one waits on conditional variables. ~InfLenFIFOQueue(); // Puts elem into queue immediately at the end of queue. Since the queue has @@ -86,7 +86,7 @@ class InfLenFIFOQueue : public MPMCQueueInterface { Node(void* c) : content(c) { next = nullptr; - insert_time = gpr_now(GPR_CLOCK_PRECISE); + insert_time = gpr_now(GPR_CLOCK_MONOTONIC); } }; From 23028dd12d774a5fefa1c9f597b7942a2b6dae2d Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 25 Jun 2019 19:45:04 -0700 Subject: [PATCH 472/676] Change trace flag var name --- src/core/lib/iomgr/executor/mpmcqueue.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 2bc3ffbc392..93b1d195f46 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -76,8 +76,8 @@ void InfLenFIFOQueue::Put(void* elem) { MutexLock l(&mu_); Node* new_node = New(elem); - if (count_.Load(MemoryOrder::RELAXED) == 0) { - if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + if (count_.FetchAdd(1, MemoryOrder::RELAXED) == 0) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { busy_time = gpr_now(GPR_CLOCK_MONOTONIC); } queue_head_ = queue_tail_ = new_node; @@ -85,10 +85,10 @@ void InfLenFIFOQueue::Put(void* elem) { queue_tail_->next = new_node; queue_tail_ = queue_tail_->next; } - count_.FetchAdd(1, MemoryOrder::RELAXED); + // Updates Stats info - if (GRPC_TRACE_FLAG_ENABLED(thread_pool)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { stats_.num_started++; gpr_log(GPR_INFO, "[InfLenFIFOQueue Put] num_started: %" PRIu64, stats_.num_started); From c041acb7a7371d3b5bdb1d5ecfdcfd201eb90e2c Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 25 Jun 2019 20:09:06 -0700 Subject: [PATCH 473/676] Fix the unit tests to exercise nesting correctly. --- .../end2end/client_callback_end2end_test.cc | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 52797672fc0..b80f612b3a2 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -382,62 +382,37 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { bool done1 = false; EchoRequest request1, request2, request3; request1.set_message("Hello locked world1."); - EchoResponse response1; - ClientContext cli_ctx1; + request2.set_message("Hello locked world2."); + request3.set_message("Hello locked world3."); + EchoResponse response1, response2, response3; + ClientContext cli_ctx1, cli_ctx2, cli_ctx3; { std::unique_lock l(mu1); stub_->experimental_async()->Echo( &cli_ctx1, &request1, &response1, - [&mu1, this, &cv1, &done1, &request1, &response1](Status s1) { + [this, &mu1, &mu2, &mu3, &cv1, &done1, &request1, &request2, &request3, &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, &cli_ctx3](Status s1) { std::unique_lock l1(mu1); EXPECT_TRUE(s1.ok()); EXPECT_EQ(request1.message(), response1.message()); // start the second level of nesting - std::mutex mu2; - bool done2 = false; - std::condition_variable cv2; - EchoRequest request2; - request2.set_message("Hello locked world2."); - EchoResponse response2; - ClientContext cli_ctx2; std::unique_lock l2(mu2); - stub_->experimental_async()->Echo( - &cli_ctx2, &request2, &response2, - [&mu2, this, &cv2, &done2, &request2, &response2](Status s2) { + this->stub_->experimental_async()->Echo(&cli_ctx2, &request2, &response2, + [this, &mu2, &mu3, &cv1, &done1, &request2, &request3, &response2, &response3, &cli_ctx3](Status s2) { std::unique_lock l2(mu2); EXPECT_TRUE(s2.ok()); EXPECT_EQ(request2.message(), response2.message()); // start the third level of nesting - std::mutex mu3; - bool done3 = false; - std::condition_variable cv3; - EchoRequest request3; - request3.set_message("Hello locked world2."); - EchoResponse response3; - ClientContext cli_ctx3; std::unique_lock l3(mu3); stub_->experimental_async()->Echo( &cli_ctx3, &request3, &response3, - [&mu3, &cv3, &done3, &request3, &response3](Status s3) { + [&mu3, &cv1, &done1, &request3, &response3](Status s3) { std::lock_guard l(mu3); EXPECT_TRUE(s3.ok()); EXPECT_EQ(request3.message(), response3.message()); - done3 = true; - cv3.notify_all(); + done1 = true; + cv1.notify_all(); }); - done2 = true; - cv2.notify_all(); - // Wait for inner most rpc to return. - while (!done3) { - cv3.wait(l3); - } }); - // Wait for second rpc to return. - while (!done2) { - cv2.wait(l2); - } - done1 = true; - cv1.notify_all(); }); } From 3467f2dfdc302896a3fc0132a63983aeecb42b8e Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 25 Jun 2019 20:10:43 -0700 Subject: [PATCH 474/676] Fix log typo --- .../resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index df40ba1c4bd..d24c111448c 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -353,7 +353,7 @@ class GrpcPolledFdWindows : public GrpcPolledFd { ares_ssize_t SendV(WSAErrorContext* wsa_error_ctx, const struct iovec* iov, int iov_count) { GRPC_CARES_TRACE_LOG( - "fd:|%s| SendV called connect_done_:%d was_connect_error_:%d", + "fd:|%s| SendV called connect_done_:%d wsa_connect_error_:%d", GetName(), connect_done_, wsa_connect_error_); if (!connect_done_) { wsa_error_ctx->SetWSAError(WSAEWOULDBLOCK); From 514413de70d2992e23d2ca6eac3adcca73c9d5f4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 25 Jun 2019 20:14:15 -0700 Subject: [PATCH 475/676] Clang formatting errors --- test/cpp/end2end/client_callback_end2end_test.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index b80f612b3a2..8c33dc85cfc 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -390,14 +390,18 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { std::unique_lock l(mu1); stub_->experimental_async()->Echo( &cli_ctx1, &request1, &response1, - [this, &mu1, &mu2, &mu3, &cv1, &done1, &request1, &request2, &request3, &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, &cli_ctx3](Status s1) { + [this, &mu1, &mu2, &mu3, &cv1, &done1, &request1, &request2, &request3, + &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, + &cli_ctx3](Status s1) { std::unique_lock l1(mu1); EXPECT_TRUE(s1.ok()); EXPECT_EQ(request1.message(), response1.message()); // start the second level of nesting std::unique_lock l2(mu2); - this->stub_->experimental_async()->Echo(&cli_ctx2, &request2, &response2, - [this, &mu2, &mu3, &cv1, &done1, &request2, &request3, &response2, &response3, &cli_ctx3](Status s2) { + this->stub_->experimental_async()->Echo( + &cli_ctx2, &request2, &response2, + [this, &mu2, &mu3, &cv1, &done1, &request2, &request3, &response2, + &response3, &cli_ctx3](Status s2) { std::unique_lock l2(mu2); EXPECT_TRUE(s2.ok()); EXPECT_EQ(request2.message(), response2.message()); From a827504ffb70cbb8e25e976958853752f1cf5399 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Jun 2019 11:22:48 +0200 Subject: [PATCH 476/676] get rid of workaround to build net45 targets on linux and mac --- src/csharp/Grpc.Core/Common.csproj.include | 10 ++++------ .../Grpc.Tools.Tests/Grpc.Tools.Tests.csproj | 15 ++++----------- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 15 ++++----------- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/csharp/Grpc.Core/Common.csproj.include b/src/csharp/Grpc.Core/Common.csproj.include index 3b1bec2d55f..19e7240f443 100755 --- a/src/csharp/Grpc.Core/Common.csproj.include +++ b/src/csharp/Grpc.Core/Common.csproj.include @@ -19,10 +19,8 @@ true - - - /usr/lib/mono/4.5-api - /usr/local/lib/mono/4.5-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api - + + + + diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index 7ad2ce21694..6df929cb2c0 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -7,17 +7,10 @@ - - - - /usr/lib/mono/4.5-api - /usr/local/lib/mono/4.5-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api - + + + + diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index d09d97d1397..40034e9b20a 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -7,17 +7,10 @@ net45;netstandard1.3 - - - - /usr/lib/mono/4.5-api - /usr/local/lib/mono/4.5-api - /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api - + + + + From 8bfb713c8052d8af27a9f12eb2922623b3ec7fe2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 26 Jun 2019 04:38:44 -0400 Subject: [PATCH 477/676] fix Grpc.Tools build --- src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj | 12 ++++++++---- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index 6df929cb2c0..bc32e375860 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -7,10 +7,14 @@ - - - - + + + /usr/lib/mono/4.5-api + /usr/local/lib/mono/4.5-api + /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api + diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 40034e9b20a..e73f7b7deae 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -7,10 +7,14 @@ net45;netstandard1.3 - - - - + + + /usr/lib/mono/4.5-api + /usr/local/lib/mono/4.5-api + /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5-api + From 03b063568d9b8ce416134952e57198ce2a1c4a8f Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 26 Jun 2019 08:56:52 -0700 Subject: [PATCH 478/676] Minor fixes --- src/core/ext/filters/client_channel/client_channel_channelz.cc | 3 +-- src/core/ext/filters/client_channel/client_channel_channelz.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index f21d45d8c0f..3076c1c1420 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -47,8 +47,7 @@ void SubchannelNode::SetChildSocketUuid(intptr_t uuid) { } void SubchannelNode::PopulateConnectivityState(grpc_json* json) { - grpc_connectivity_state state; - state = connectivity_state_.Load(MemoryOrder::RELAXED); + grpc_connectivity_state state = connectivity_state_.Load(MemoryOrder::RELAXED); json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); grpc_json_create_child(nullptr, json, "state", diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index d5aa20ca9a1..80a6fd230c8 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -37,7 +37,7 @@ class SubchannelNode : public BaseNode { SubchannelNode(const char* target_address, size_t channel_tracer_max_nodes); ~SubchannelNode() override; - // Used when the subchannel's connectivity state changes. + // Sets the subchannel's connectivity state without health checking. void UpdateConnectivityState(grpc_connectivity_state state); // Used when the subchannel's child socket uuid changes. This should be set From 7f666a25ff54a72ef90a2b8126119430a78c05aa Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 26 Jun 2019 09:21:42 -0700 Subject: [PATCH 479/676] Remove GetC/hildSocketUuid and stop storing uuid inside ConnectedSubchannel --- .../ext/filters/client_channel/subchannel.cc | 16 +++------------- src/core/ext/filters/client_channel/subchannel.h | 8 +------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 8ed821e236e..b6ab47fb09d 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -84,13 +84,11 @@ DebugOnlyTraceFlag grpc_trace_subchannel_refcount(false, "subchannel_refcount"); ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - RefCountedPtr channelz_subchannel, - intptr_t socket_uuid) + RefCountedPtr channelz_subchannel) : ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount), channel_stack_(channel_stack), args_(grpc_channel_args_copy(args)), - channelz_subchannel_(std::move(channelz_subchannel)), - socket_uuid_(socket_uuid) {} + channelz_subchannel_(std::move(channelz_subchannel)) {} ConnectedSubchannel::~ConnectedSubchannel() { grpc_channel_args_destroy(args_); @@ -781,14 +779,6 @@ Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { } } -intptr_t Subchannel::GetChildSocketUuid() { - if (connected_subchannel_ != nullptr) { - return connected_subchannel_->socket_uuid(); - } else { - return 0; - } -} - const char* Subchannel::GetTargetAddress() { const grpc_arg* addr_arg = grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS); @@ -1082,7 +1072,7 @@ bool Subchannel::PublishTransportLocked() { } // Publish. connected_subchannel_.reset( - New(stk, args_, channelz_node_, socket_uuid)); + New(stk, args_, channelz_node_)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", connected_subchannel_.get(), this); if (channelz_node_ != nullptr) { diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 2f05792b872..64d679af6c5 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -85,8 +85,7 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - RefCountedPtr channelz_subchannel, - intptr_t socket_uuid); + RefCountedPtr channelz_subchannel); ~ConnectedSubchannel(); void NotifyOnStateChange(grpc_pollset_set* interested_parties, @@ -101,7 +100,6 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { channelz::SubchannelNode* channelz_subchannel() const { return channelz_subchannel_.get(); } - intptr_t socket_uuid() const { return socket_uuid_; } size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; @@ -111,8 +109,6 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. RefCountedPtr channelz_subchannel_; - // uuid of this subchannel's socket. 0 if this subchannel is not connected. - const intptr_t socket_uuid_; }; // Implements the interface of RefCounted<>. @@ -200,8 +196,6 @@ class Subchannel { // returns null. Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - intptr_t GetChildSocketUuid(); - // Gets the string representing the subchannel address. // Caller doesn't take ownership. const char* GetTargetAddress(); From 51626535cdf80076eb9b543540dccac54066e8b4 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 26 Jun 2019 09:33:58 -0700 Subject: [PATCH 480/676] Fix BUILD file --- BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/BUILD b/BUILD index 35e10a8b2ff..172a90e151e 100644 --- a/BUILD +++ b/BUILD @@ -2189,7 +2189,6 @@ grpc_cc_library( "include/grpcpp/impl/codegen/server_callback.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", - "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", "include/grpcpp/impl/codegen/server_interface.h", "include/grpcpp/impl/codegen/service_type.h", From c48eac2dd47db64003008b57e6dcc98f0876c309 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 26 Jun 2019 09:35:59 -0700 Subject: [PATCH 481/676] Modify variable name for consistency, remove extra test --- src/core/lib/iomgr/executor/mpmcqueue.cc | 1 - test/core/iomgr/mpmcqueue_test.cc | 127 ++++++++--------------- 2 files changed, 42 insertions(+), 86 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 93b1d195f46..c6c2b7d0cc1 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -86,7 +86,6 @@ void InfLenFIFOQueue::Put(void* elem) { queue_tail_ = queue_tail_->next; } - // Updates Stats info if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { stats_.num_started++; diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 792d9b602c2..cd29362e557 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -23,7 +23,7 @@ #include "src/core/lib/gprpp/thd.h" #include "test/core/util/test_config.h" -#define THREAD_LARGE_ITERATION 10000 +#define TEST_NUM_ITEMS 10000 // Testing items for queue struct WorkItem { @@ -41,7 +41,7 @@ class ProducerThread { : start_index_(start_index), num_items_(num_items), queue_(queue) { items_ = nullptr; thd_ = grpc_core::Thread( - "mpmcq_test_put_thd", + "mpmcq_test_producer_thd", [](void* th) { static_cast(th)->Run(); }, this); } ~ProducerThread() { @@ -76,7 +76,7 @@ class ConsumerThread { public: ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) { thd_ = grpc_core::Thread( - "mpmcq_test_get_thd", + "mpmcq_test_consumer_thd", [](void* th) { static_cast(th)->Run(); }, this); } ~ConsumerThread() {} @@ -102,55 +102,14 @@ class ConsumerThread { grpc_core::Thread thd_; }; -static void test_get_empty(void) { - gpr_log(GPR_INFO, "test_get_empty"); - grpc_core::InfLenFIFOQueue queue; - GPR_ASSERT(queue.count() == 0); - const int num_threads = 10; - ConsumerThread** consumer_thds = static_cast( - gpr_zalloc(num_threads * sizeof(ConsumerThread*))); - - // Fork threads. Threads should block at the beginning since queue is empty. - for (int i = 0; i < num_threads; ++i) { - consumer_thds[i] = grpc_core::New(&queue); - consumer_thds[i]->Start(); - } - - WorkItem** items = static_cast( - gpr_zalloc(THREAD_LARGE_ITERATION * sizeof(WorkItem*))); - for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - items[i] = grpc_core::New(i); - queue.Put(static_cast(items[i])); - } - - gpr_log(GPR_DEBUG, "Terminating threads..."); - for (int i = 0; i < num_threads; ++i) { - queue.Put(nullptr); - } - for (int i = 0; i < num_threads; ++i) { - consumer_thds[i]->Join(); - } - gpr_log(GPR_DEBUG, "Checking and Cleaning Up..."); - for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { - GPR_ASSERT(items[i]->done); - grpc_core::Delete(items[i]); - } - gpr_free(items); - for (int i = 0; i < num_threads; ++i) { - grpc_core::Delete(consumer_thds[i]); - } - gpr_free(consumer_thds); - gpr_log(GPR_DEBUG, "Done."); -} - static void test_FIFO(void) { gpr_log(GPR_INFO, "test_FIFO"); grpc_core::InfLenFIFOQueue large_queue; - for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + for (int i = 0; i < TEST_NUM_ITEMS; ++i) { large_queue.Put(static_cast(grpc_core::New(i))); } - GPR_ASSERT(large_queue.count() == THREAD_LARGE_ITERATION); - for (int i = 0; i < THREAD_LARGE_ITERATION; ++i) { + GPR_ASSERT(large_queue.count() == TEST_NUM_ITEMS); + for (int i = 0; i < TEST_NUM_ITEMS; ++i) { WorkItem* item = static_cast(large_queue.Get()); GPR_ASSERT(i == item->index); grpc_core::Delete(item); @@ -159,57 +118,55 @@ static void test_FIFO(void) { static void test_many_thread(void) { gpr_log(GPR_INFO, "test_many_thread"); - const int num_work_thd = 10; - const int num_get_thd = 20; + const int num_producer_threads = 10; + const int num_consumer_threads = 20; grpc_core::InfLenFIFOQueue queue; - ProducerThread** work_thds = static_cast( - gpr_zalloc(num_work_thd * sizeof(ProducerThread*))); - ConsumerThread** consumer_thds = static_cast( - gpr_zalloc(num_get_thd * sizeof(ConsumerThread*))); - - gpr_log(GPR_DEBUG, "Fork ProducerThread..."); - for (int i = 0; i < num_work_thd; ++i) { - work_thds[i] = grpc_core::New( - &queue, i * THREAD_LARGE_ITERATION, THREAD_LARGE_ITERATION); - work_thds[i]->Start(); - } - gpr_log(GPR_DEBUG, "ProducerThread Started."); - gpr_log(GPR_DEBUG, "Fork Getter Thread..."); - for (int i = 0; i < num_get_thd; ++i) { - consumer_thds[i] = grpc_core::New(&queue); - consumer_thds[i]->Start(); - } - gpr_log(GPR_DEBUG, "Getter Thread Started."); - gpr_log(GPR_DEBUG, "Waiting ProducerThread to finish..."); - for (int i = 0; i < num_work_thd; ++i) { - work_thds[i]->Join(); - } - gpr_log(GPR_DEBUG, "All ProducerThread Terminated."); - gpr_log(GPR_DEBUG, "Terminating Getter Thread..."); - for (int i = 0; i < num_get_thd; ++i) { + ProducerThread** producer_threads = static_cast( + gpr_zalloc(num_producer_threads * sizeof(ProducerThread*))); + ConsumerThread** consumer_threads = static_cast( + gpr_zalloc(num_consumer_threads * sizeof(ConsumerThread*))); + + gpr_log(GPR_DEBUG, "Fork ProducerThreads..."); + for (int i = 0; i < num_producer_threads; ++i) { + producer_threads[i] = grpc_core::New( + &queue, i * TEST_NUM_ITEMS, TEST_NUM_ITEMS); + producer_threads[i]->Start(); + } + gpr_log(GPR_DEBUG, "ProducerThreads Started."); + gpr_log(GPR_DEBUG, "Fork ConsumerThreads..."); + for (int i = 0; i < num_consumer_threads; ++i) { + consumer_threads[i] = grpc_core::New(&queue); + consumer_threads[i]->Start(); + } + gpr_log(GPR_DEBUG, "ConsumerThreads Started."); + gpr_log(GPR_DEBUG, "Waiting ProducerThreads to finish..."); + for (int i = 0; i < num_producer_threads; ++i) { + producer_threads[i]->Join(); + } + gpr_log(GPR_DEBUG, "All ProducerThreads Terminated."); + gpr_log(GPR_DEBUG, "Terminating ConsumerThreads..."); + for (int i = 0; i < num_consumer_threads; ++i) { queue.Put(nullptr); } - for (int i = 0; i < num_get_thd; ++i) { - consumer_thds[i]->Join(); + for (int i = 0; i < num_consumer_threads; ++i) { + consumer_threads[i]->Join(); } - gpr_log(GPR_DEBUG, "All Getter Thread Terminated."); + gpr_log(GPR_DEBUG, "All ConsumerThreads Terminated."); gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); - for (int i = 0; i < num_work_thd; ++i) { - grpc_core::Delete(work_thds[i]); + for (int i = 0; i < num_producer_threads; ++i) { + grpc_core::Delete(producer_threads[i]); } - gpr_free(work_thds); - for (int i = 0; i < num_get_thd; ++i) { - grpc_core::Delete(consumer_thds[i]); + gpr_free(producer_threads); + for (int i = 0; i < num_consumer_threads; ++i) { + grpc_core::Delete(consumer_threads[i]); } - gpr_free(consumer_thds); + gpr_free(consumer_threads); gpr_log(GPR_DEBUG, "Done."); } int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); - gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); - test_get_empty(); test_FIFO(); test_many_thread(); grpc_shutdown(); From ce41cde908a61468de83623453ff1984bf18ea7f Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 25 Jun 2019 14:08:41 -0700 Subject: [PATCH 482/676] Fix string/bytes problem && lint --- examples/python/auth/_credentials.py | 4 ++-- examples/python/auth/customized_auth_client.py | 7 ------- examples/python/auth/customized_auth_server.py | 7 ------- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/examples/python/auth/_credentials.py b/examples/python/auth/_credentials.py index 39939f6284b..732587b7c5b 100644 --- a/examples/python/auth/_credentials.py +++ b/examples/python/auth/_credentials.py @@ -22,8 +22,8 @@ import os def _load_credential_from_file(filepath): real_path = os.path.join(os.path.dirname(__file__), filepath) - with open(real_path, 'r') as f: - return bytes(f.read()) + with open(real_path, 'rb') as f: + return f.read() SERVER_CERTIFICATE = _load_credential_from_file('credentials/localhost.crt') diff --git a/examples/python/auth/customized_auth_client.py b/examples/python/auth/customized_auth_client.py index 4ec0c2d3806..0236c07adb1 100644 --- a/examples/python/auth/customized_auth_client.py +++ b/examples/python/auth/customized_auth_client.py @@ -20,7 +20,6 @@ from __future__ import print_function import argparse import contextlib import logging -import os import grpc from examples import helloworld_pb2 @@ -57,12 +56,6 @@ class AuthGateway(grpc.AuthMetadataPlugin): callback(((_SIGNATURE_HEADER_KEY, signature),), None) -def _load_credential_from_file(filepath): - real_path = os.path.join(os.path.dirname(__file__), filepath) - with open(real_path, 'r') as f: - return f.read() - - @contextlib.contextmanager def create_client_channel(addr): # Call credential object will be invoked for every single RPC diff --git a/examples/python/auth/customized_auth_server.py b/examples/python/auth/customized_auth_server.py index f79c2639d90..1debc6c3c5f 100644 --- a/examples/python/auth/customized_auth_server.py +++ b/examples/python/auth/customized_auth_server.py @@ -20,7 +20,6 @@ from __future__ import print_function import argparse import contextlib import logging -import os import time from concurrent import futures @@ -66,12 +65,6 @@ class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) -def _load_credential_from_file(filepath): - real_path = os.path.join(os.path.dirname(__file__), filepath) - with open(real_path, 'r') as f: - return f.read() - - @contextlib.contextmanager def run_server(port): # Bind interceptor to server From 833bd5c118c4f09af42b9366fe47de31a42f9ac7 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 26 Jun 2019 10:12:50 -0700 Subject: [PATCH 483/676] Change trace flag name, add some comment in test --- src/core/lib/iomgr/executor/mpmcqueue.cc | 2 +- test/core/iomgr/mpmcqueue_test.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index c6c2b7d0cc1..97429ec30c7 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -22,7 +22,7 @@ namespace grpc_core { -DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool_trace"); +DebugOnlyTraceFlag grpc_thread_pool_trace(false, "thread_pool"); inline void* InfLenFIFOQueue::PopFront() { // Caller should already check queue is not empty and has already held the diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index cd29362e557..12107e85327 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -154,6 +154,7 @@ static void test_many_thread(void) { gpr_log(GPR_DEBUG, "All ConsumerThreads Terminated."); gpr_log(GPR_DEBUG, "Checking WorkItems and Cleaning Up..."); for (int i = 0; i < num_producer_threads; ++i) { + // Destructor of ProducerThread will do the check of WorkItems grpc_core::Delete(producer_threads[i]); } gpr_free(producer_threads); From 5a05ea0530e6c9dde26c631e12e129f882c7a750 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 26 Jun 2019 10:21:06 -0700 Subject: [PATCH 484/676] Format --- src/core/ext/filters/client_channel/client_channel_channelz.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 3076c1c1420..a489685df40 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -47,7 +47,8 @@ void SubchannelNode::SetChildSocketUuid(intptr_t uuid) { } void SubchannelNode::PopulateConnectivityState(grpc_json* json) { - grpc_connectivity_state state = connectivity_state_.Load(MemoryOrder::RELAXED); + grpc_connectivity_state state = + connectivity_state_.Load(MemoryOrder::RELAXED); json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); grpc_json_create_child(nullptr, json, "state", From ef4388b862aebacac70231b9040ef7a668e87e7b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 26 Jun 2019 11:31:24 -0700 Subject: [PATCH 485/676] Explain order of callback execution in executor comments --- src/core/lib/iomgr/executor.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 8adc0902bd1..721542544cd 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -120,7 +120,10 @@ size_t Executor::RunClosures(const char* executor_name, // thread itself, but this is the point where we could start seeing // application-level callbacks. No need to create a new ExecCtx, though, // since there already is one and it is flushed (but not destructed) in this - // function itself. + // function itself. The ApplicationCallbackExecCtx will have its callbacks + // invoked on its destruction, which will be after completing any closures in + // the executor's closure list (which were explicitly scheduled onto the + // executor). grpc_core::ApplicationCallbackExecCtx callback_exec_ctx( GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); From 4ad6d6d4dfefd1e7892d808ce29adfa3a8b49d82 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 26 Jun 2019 10:33:06 -0700 Subject: [PATCH 486/676] Enable CFStream by default on iOS for all wrapped languages --- CMakeLists.txt | 18 ++++++++++++++++++ Makefile | 1 + src/core/lib/iomgr/iomgr_posix_cfstream.cc | 10 ++++++++++ src/objective-c/GRPCClient/GRPCCall.m | 5 +---- src/objective-c/manual_tests/main.m | 2 -- templates/CMakeLists.txt.template | 7 +++++++ templates/Makefile.template | 1 + 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19c8d44b05d..40757101a7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1364,6 +1364,9 @@ target_link_libraries(grpc ${_gRPC_ALLTARGETS_LIBRARIES} gpr ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc "-framework CoreFoundation") +endif() foreach(_hdr include/grpc/impl/codegen/byte_buffer.h @@ -1762,6 +1765,9 @@ target_link_libraries(grpc_cronet ${_gRPC_ALLTARGETS_LIBRARIES} gpr ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_cronet "-framework CoreFoundation") +endif() foreach(_hdr include/grpc/impl/codegen/byte_buffer.h @@ -2091,6 +2097,9 @@ target_link_libraries(grpc_test_util gpr grpc ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_test_util "-framework CoreFoundation") +endif() foreach(_hdr include/grpc/support/alloc.h @@ -2421,6 +2430,9 @@ target_link_libraries(grpc_test_util_unsecure gpr grpc_unsecure ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_test_util_unsecure "-framework CoreFoundation") +endif() foreach(_hdr include/grpc/support/alloc.h @@ -2774,6 +2786,9 @@ target_link_libraries(grpc_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} gpr ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc_unsecure "-framework CoreFoundation") +endif() foreach(_hdr include/grpc/impl/codegen/byte_buffer.h @@ -3729,6 +3744,9 @@ target_link_libraries(grpc++_cronet grpc_cronet grpc ) +if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(grpc++_cronet "-framework CoreFoundation") +endif() foreach(_hdr include/grpc++/alarm.h diff --git a/Makefile b/Makefile index 2d28e7b5656..e3ce968cfdc 100644 --- a/Makefile +++ b/Makefile @@ -351,6 +351,7 @@ CFLAGS += -std=c99 -Wsign-conversion -Wconversion $(W_SHADOW) $(W_EXTRA_SEMI) CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ +LDFLAGS += -framework CoreFoundation endif CXXFLAGS += -Wnon-virtual-dtor CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index cf4d05318ea..6e1bbae032e 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -78,9 +78,19 @@ static grpc_iomgr_platform_vtable vtable = { void grpc_set_default_iomgr_platform() { char* enable_cfstream = getenv(grpc_cfstream_env_var); grpc_tcp_client_vtable* client_vtable = &grpc_posix_tcp_client_vtable; + // CFStream is enabled by default on iOS, and disabled by default on other + // platforms. Defaults can be overriden by setting the grpc_cfstream + // environment variable. +#if TARGET_OS_IPHONE + if (enable_cfstream == nullptr || enable_cfstream[0] == '1') { + client_vtable = &grpc_cfstream_client_vtable; + } +#else if (enable_cfstream != nullptr && enable_cfstream[0] == '1') { client_vtable = &grpc_cfstream_client_vtable; } +#endif + grpc_set_tcp_client_impl(client_vtable); grpc_set_tcp_server_impl(&grpc_posix_tcp_server_vtable); grpc_set_timer_impl(&grpc_generic_timer_vtable); diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e97ed6e3a9e..b5dfade0c39 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -322,9 +322,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Guarantees the code in {} block is invoked only once. See ref at: // https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=objc if (self == [GRPCCall self]) { - // Enable CFStream by default by do not overwrite if the user explicitly disables CFStream with - // environment variable "grpc_cfstream=0" - setenv(kCFStreamVarName, "1", 0); grpc_init(); callFlags = [NSMutableDictionary dictionary]; } @@ -780,7 +777,7 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { + if (enableCFStream != nil && enableCFStream[0] != '1') { [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; } } diff --git a/src/objective-c/manual_tests/main.m b/src/objective-c/manual_tests/main.m index 451b50cc0e2..2797c6f17f2 100644 --- a/src/objective-c/manual_tests/main.m +++ b/src/objective-c/manual_tests/main.m @@ -21,8 +21,6 @@ int main(int argc, char* argv[]) { @autoreleasepool { - // enable CFStream API - setenv("grpc_cfstream", "1", 1); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 43bc063aee5..abf1282fe51 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -467,6 +467,13 @@ ) endif (_gRPC_PLATFORM_ANDROID) % endif + % if lib.name in ["grpc", "grpc_cronet", "grpc_test_util", \ + "grpc_test_util_unsecure", "grpc_unsecure", \ + "grpc++_cronet"]: + if (_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC) + target_link_libraries(${lib.name} "-framework CoreFoundation") + endif() + %endif % if len(lib.get('public_headers', [])) > 0: foreach(_hdr diff --git a/templates/Makefile.template b/templates/Makefile.template index 24bea5c2423..18132b0db13 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -220,6 +220,7 @@ CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ + LDFLAGS += -framework CoreFoundation endif % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'COREFLAGS', 'LDFLAGS', 'DEFINES']: % if defaults.get('global', []).get(arg, None) is not None: From 2602bdd3e404849421a0be78c7f023057b4b9872 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 26 Jun 2019 11:37:54 -0700 Subject: [PATCH 487/676] Address review comments --- src/core/lib/surface/completion_queue.cc | 4 +-- .../end2end/client_callback_end2end_test.cc | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 55bfb6fcc30..82f87e769bf 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -864,7 +864,7 @@ static void cq_end_op_for_callback( return; } - // Schedule the shutdown callback on a closure if not internal or triggered + // Schedule the callback on a closure if not internal or triggered // from a background poller thread. GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( @@ -1360,7 +1360,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { return; } - // Schedule the shutdown callback on a closure if not internal or triggered + // Schedule the callback on a closure if not internal or triggered // from a background poller thread. GRPC_CLOSURE_SCHED( GRPC_CLOSURE_CREATE( diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 8c33dc85cfc..ea94ac77726 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -378,8 +378,8 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { MAYBE_SKIP_TEST; ResetStub(); std::mutex mu1, mu2, mu3; - std::condition_variable cv1, cv2, cv3; - bool done1 = false; + std::condition_variable cv; + bool done = false; EchoRequest request1, request2, request3; request1.set_message("Hello locked world1."); request2.set_message("Hello locked world2."); @@ -387,42 +387,42 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { EchoResponse response1, response2, response3; ClientContext cli_ctx1, cli_ctx2, cli_ctx3; { - std::unique_lock l(mu1); + std::lock_guard l(mu1); stub_->experimental_async()->Echo( &cli_ctx1, &request1, &response1, - [this, &mu1, &mu2, &mu3, &cv1, &done1, &request1, &request2, &request3, + [this, &mu1, &mu2, &mu3, &cv, &done, &request1, &request2, &request3, &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, &cli_ctx3](Status s1) { - std::unique_lock l1(mu1); + std::lock_guard l1(mu1); EXPECT_TRUE(s1.ok()); EXPECT_EQ(request1.message(), response1.message()); // start the second level of nesting std::unique_lock l2(mu2); this->stub_->experimental_async()->Echo( &cli_ctx2, &request2, &response2, - [this, &mu2, &mu3, &cv1, &done1, &request2, &request3, &response2, + [this, &mu2, &mu3, &cv, &done, &request2, &request3, &response2, &response3, &cli_ctx3](Status s2) { - std::unique_lock l2(mu2); + std::lock_guard l2(mu2); EXPECT_TRUE(s2.ok()); EXPECT_EQ(request2.message(), response2.message()); // start the third level of nesting - std::unique_lock l3(mu3); + std::lock_guard l3(mu3); stub_->experimental_async()->Echo( &cli_ctx3, &request3, &response3, - [&mu3, &cv1, &done1, &request3, &response3](Status s3) { + [&mu3, &cv, &done, &request3, &response3](Status s3) { std::lock_guard l(mu3); EXPECT_TRUE(s3.ok()); EXPECT_EQ(request3.message(), response3.message()); - done1 = true; - cv1.notify_all(); + done = true; + cv.notify_all(); }); }); }); } - std::unique_lock l1(mu1); - while (!done1) { - cv1.wait(l1); + std::unique_lock l(mu3); + while (!done) { + cv.wait(l); } } From 748b932d0233ffdbc2faa2038d96e3b384219be1 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 26 Jun 2019 12:32:31 -0700 Subject: [PATCH 488/676] Fix header guards --- include/grpcpp/completion_queue_impl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/completion_queue_impl.h b/include/grpcpp/completion_queue_impl.h index d5bb07d5763..b6fb2b4f990 100644 --- a/include/grpcpp/completion_queue_impl.h +++ b/include/grpcpp/completion_queue_impl.h @@ -16,9 +16,9 @@ * */ -#ifndef GRPCPP_COMPLETION_QUEUE_H -#define GRPCPP_COMPLETION_QUEUE_H +#ifndef GRPCPP_COMPLETION_QUEUE_IMPL_H +#define GRPCPP_COMPLETION_QUEUE_IMPL_H #include -#endif // GRPCPP_COMPLETION_QUEUE_H +#endif // GRPCPP_COMPLETION_QUEUE_IMPL_H From 189c2c8c306f92586e33a355f90bd600d0cd2488 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 14 May 2019 23:06:53 -0700 Subject: [PATCH 489/676] Adding support for STS Token Exchange Creds in core: - IETF specification is available here: https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 --- grpc.def | 1 + include/grpc/grpc_security.h | 25 ++ .../security/credentials/jwt/json_token.cc | 8 +- .../credentials/oauth2/oauth2_credentials.cc | 258 +++++++++++++-- .../credentials/oauth2/oauth2_credentials.h | 16 + src/core/lib/security/util/json_util.cc | 24 +- src/core/lib/security/util/json_util.h | 4 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + test/core/security/credentials_test.cc | 305 +++++++++++++++++- test/core/security/fetch_oauth2.cc | 82 ++++- test/core/security/oauth2_utils.cc | 15 +- .../core/surface/public_headers_must_be_c89.c | 1 + 13 files changed, 692 insertions(+), 52 deletions(-) diff --git a/grpc.def b/grpc.def index 32289dffeb7..f451775dba6 100644 --- a/grpc.def +++ b/grpc.def @@ -111,6 +111,7 @@ EXPORTS grpc_google_refresh_token_credentials_create grpc_access_token_credentials_create grpc_google_iam_credentials_create + grpc_sts_credentials_create grpc_metadata_credentials_create_from_plugin grpc_secure_channel_create grpc_server_credentials_release diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 139c0c37a1f..8e4f26a2854 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -328,6 +328,31 @@ GRPCAPI grpc_call_credentials* grpc_google_iam_credentials_create( const char* authorization_token, const char* authority_selector, void* reserved); +/** Options for creating STS Oauth Token Exchange credentials following the IETF + draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16. + Optional fields may be set to NULL. It is the responsibility of the caller to + ensure that the subject and actor tokens are refreshed on disk at the + specified paths. This API is used for experimental purposes for now and may + change in the future. */ +typedef struct { + const char* sts_endpoint_url; /* Required. */ + const char* resource; /* Optional. */ + const char* audience; /* Optional. */ + const char* scope; /* Optional. */ + const char* requested_token_type; /* Optional. */ + const char* subject_token_path; /* Required. */ + const char* subject_token_type; /* Required. */ + const char* actor_token_path; /* Optional. */ + const char* actor_token_type; /* Optional. */ +} grpc_sts_credentials_options; + +/** Creates an STS credentials following the STS Token Exchanged specifed in the + IETF draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16. + This API is used for experimental purposes for now and may change in the + future. */ +GRPCAPI grpc_call_credentials* grpc_sts_credentials_create( + const grpc_sts_credentials_options* options, void* reserved); + /** Callback function to be called by the metadata credentials plugin implementation when the metadata is ready. - user_data is the opaque pointer that was passed in the get_metadata method diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc index 113e2b83754..12b7c5368da 100644 --- a/src/core/lib/security/credentials/jwt/json_token.cc +++ b/src/core/lib/security/credentials/jwt/json_token.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/jwt/json_token.h" #include @@ -69,6 +70,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) { BIO* bio = nullptr; const char* prop_value; int success = 0; + grpc_error* error = GRPC_ERROR_NONE; memset(&result, 0, sizeof(grpc_auth_json_key)); result.type = GRPC_AUTH_JSON_TYPE_INVALID; @@ -77,7 +79,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) { goto end; } - prop_value = grpc_json_get_string_property(json, "type"); + prop_value = grpc_json_get_string_property(json, "type", &error); + GRPC_LOG_IF_ERROR("JSON key parsing", error); if (prop_value == nullptr || strcmp(prop_value, GRPC_AUTH_JSON_TYPE_SERVICE_ACCOUNT)) { goto end; @@ -92,7 +95,8 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const grpc_json* json) { goto end; } - prop_value = grpc_json_get_string_property(json, "private_key"); + prop_value = grpc_json_get_string_property(json, "private_key", &error); + GRPC_LOG_IF_ERROR("JSON key parsing", error); if (prop_value == nullptr) { goto end; } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index b001868b3d3..3d63ec12b49 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -22,14 +22,23 @@ #include -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/security/util/json_util.h" -#include "src/core/lib/surface/api_trace.h" - +#include +#include +#include #include #include #include +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/security/util/json_util.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/uri/uri_parser.h" + // // Auth Refresh Token. // @@ -45,6 +54,7 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( grpc_auth_refresh_token result; const char* prop_value; int success = 0; + grpc_error* error = GRPC_ERROR_NONE; memset(&result, 0, sizeof(grpc_auth_refresh_token)); result.type = GRPC_AUTH_JSON_TYPE_INVALID; @@ -53,7 +63,8 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_json( goto end; } - prop_value = grpc_json_get_string_property(json, "type"); + prop_value = grpc_json_get_string_property(json, "type", &error); + GRPC_LOG_IF_ERROR("Parsing refresh token", error); if (prop_value == nullptr || strcmp(prop_value, GRPC_AUTH_JSON_TYPE_AUTHORIZED_USER)) { goto end; @@ -218,8 +229,10 @@ void grpc_oauth2_token_fetcher_credentials::on_http_response( grpc_mdelem access_token_md = GRPC_MDNULL; grpc_millis token_lifetime; grpc_credentials_status status = - grpc_oauth2_token_fetcher_credentials_parse_server_response( - &r->response, &access_token_md, &token_lifetime); + error == GRPC_ERROR_NONE + ? grpc_oauth2_token_fetcher_credentials_parse_server_response( + &r->response, &access_token_md, &token_lifetime) + : GRPC_CREDENTIALS_ERROR; // Update cache and grab list of pending requests. gpr_mu_lock(&mu_); token_fetch_pending_ = false; @@ -234,14 +247,15 @@ void grpc_oauth2_token_fetcher_credentials::on_http_response( gpr_mu_unlock(&mu_); // Invoke callbacks for all pending requests. while (pending_request != nullptr) { + grpc_error* new_error = GRPC_ERROR_NONE; if (status == GRPC_CREDENTIALS_OK) { grpc_credentials_mdelem_array_add(pending_request->md_array, access_token_md); } else { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Error occurred when fetching oauth2 token.", &error, 1); } - GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error); + GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, new_error); grpc_polling_entity_del_from_pollset_set( pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_)); grpc_oauth2_pending_get_request_metadata* prev = pending_request; @@ -356,7 +370,8 @@ class grpc_compute_engine_token_fetcher_credentials grpc_polling_entity* pollent, grpc_iomgr_cb_func response_cb, grpc_millis deadline) override { - grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"}; + grpc_http_header header = {const_cast("Metadata-Flavor"), + const_cast("Google")}; grpc_httpcli_request request; memset(&request, 0, sizeof(grpc_httpcli_request)); request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST; @@ -369,11 +384,14 @@ class grpc_compute_engine_token_fetcher_credentials grpc_resource_quota* resource_quota = grpc_resource_quota_create("oauth2_credentials"); grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline, - GRPC_CLOSURE_CREATE(response_cb, metadata_req, - grpc_schedule_on_exec_ctx), + GRPC_CLOSURE_INIT(&http_get_cb_closure_, response_cb, + metadata_req, grpc_schedule_on_exec_ctx), &metadata_req->response); grpc_resource_quota_unref_internal(resource_quota); } + + private: + grpc_closure http_get_cb_closure_; }; } // namespace @@ -401,8 +419,9 @@ void grpc_google_refresh_token_credentials::fetch_oauth2( grpc_credentials_metadata_request* metadata_req, grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent, grpc_iomgr_cb_func response_cb, grpc_millis deadline) { - grpc_http_header header = {(char*)"Content-Type", - (char*)"application/x-www-form-urlencoded"}; + grpc_http_header header = { + const_cast("Content-Type"), + const_cast("application/x-www-form-urlencoded")}; grpc_httpcli_request request; char* body = nullptr; gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, @@ -419,11 +438,11 @@ void grpc_google_refresh_token_credentials::fetch_oauth2( extreme memory pressure. */ grpc_resource_quota* resource_quota = grpc_resource_quota_create("oauth2_credentials_refresh"); - grpc_httpcli_post( - httpcli_context, pollent, resource_quota, &request, body, strlen(body), - deadline, - GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx), - &metadata_req->response); + grpc_httpcli_post(httpcli_context, pollent, resource_quota, &request, body, + strlen(body), deadline, + GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, + metadata_req, grpc_schedule_on_exec_ctx), + &metadata_req->response); grpc_resource_quota_unref_internal(resource_quota); gpr_free(body); } @@ -472,6 +491,207 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create( .release(); } +// +// STS credentials. +// + +namespace grpc_core { + +namespace { + +void MaybeAddToBody(gpr_strvec* body_strvec, const char* field_name, + const char* field) { + if (field == nullptr || strlen(field) == 0) return; + char* new_query; + gpr_asprintf(&new_query, "&%s=%s", field_name, field); + gpr_strvec_add(body_strvec, new_query); +} + +grpc_error* LoadTokenFile(const char* path, gpr_slice* token) { + grpc_error* err = grpc_load_file(path, 1, token); + if (err != GRPC_ERROR_NONE) return err; + if (GRPC_SLICE_LENGTH(*token) == 0) { + gpr_log(GPR_ERROR, "Token file %s is empty", path); + err = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Token file is empty."); + } + return err; +} + +class StsTokenFetcherCredentials + : public grpc_oauth2_token_fetcher_credentials { + public: + StsTokenFetcherCredentials(grpc_uri* sts_url, // Ownership transfered. + const grpc_sts_credentials_options* options) + : sts_url_(sts_url), + resource_(gpr_strdup(options->resource)), + audience_(gpr_strdup(options->audience)), + scope_(gpr_strdup(options->scope)), + requested_token_type_(gpr_strdup(options->requested_token_type)), + subject_token_path_(gpr_strdup(options->subject_token_path)), + subject_token_type_(gpr_strdup(options->subject_token_type)), + actor_token_path_(gpr_strdup(options->actor_token_path)), + actor_token_type_(gpr_strdup(options->actor_token_type)) {} + + ~StsTokenFetcherCredentials() override { grpc_uri_destroy(sts_url_); } + + private: + void fetch_oauth2(grpc_credentials_metadata_request* metadata_req, + grpc_httpcli_context* http_context, + grpc_polling_entity* pollent, + grpc_iomgr_cb_func response_cb, + grpc_millis deadline) override { + char* body = nullptr; + size_t body_length = 0; + grpc_error* err = FillBody(&body, &body_length); + if (err != GRPC_ERROR_NONE) { + response_cb(metadata_req, err); + GRPC_ERROR_UNREF(err); + return; + } + grpc_http_header header = { + const_cast("Content-Type"), + const_cast("application/x-www-form-urlencoded")}; + grpc_httpcli_request request; + memset(&request, 0, sizeof(grpc_httpcli_request)); + request.host = (char*)sts_url_->authority; + request.http.path = (char*)sts_url_->path; + request.http.hdr_count = 1; + request.http.hdrs = &header; + request.handshaker = (strcmp(sts_url_->scheme, "https") == 0) + ? &grpc_httpcli_ssl + : &grpc_httpcli_plaintext; + /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + channel. This would allow us to cancel an authentication query when under + extreme memory pressure. */ + grpc_resource_quota* resource_quota = + grpc_resource_quota_create("oauth2_credentials_refresh"); + grpc_httpcli_post( + http_context, pollent, resource_quota, &request, body, body_length, + deadline, + GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req, + grpc_schedule_on_exec_ctx), + &metadata_req->response); + grpc_resource_quota_unref_internal(resource_quota); + gpr_free(body); + } + + grpc_error* FillBody(char** body, size_t* body_length) { + *body = nullptr; + gpr_strvec body_strvec; + gpr_strvec_init(&body_strvec); + grpc_slice subject_token = grpc_empty_slice(); + grpc_slice actor_token = grpc_empty_slice(); + grpc_error* err = GRPC_ERROR_NONE; + + auto cleanup = [&body, &body_length, &body_strvec, &subject_token, + &actor_token, &err]() { + if (err == GRPC_ERROR_NONE) { + *body = gpr_strvec_flatten(&body_strvec, body_length); + } else { + gpr_free(*body); + } + gpr_strvec_destroy(&body_strvec); + grpc_slice_unref_internal(subject_token); + grpc_slice_unref_internal(actor_token); + return err; + }; + + err = LoadTokenFile(subject_token_path_.get(), &subject_token); + if (err != GRPC_ERROR_NONE) return cleanup(); + gpr_asprintf( + body, GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING, + reinterpret_cast(GRPC_SLICE_START_PTR(subject_token)), + subject_token_type_.get()); + gpr_strvec_add(&body_strvec, *body); + MaybeAddToBody(&body_strvec, "resource", resource_.get()); + MaybeAddToBody(&body_strvec, "audience", audience_.get()); + MaybeAddToBody(&body_strvec, "scope", scope_.get()); + MaybeAddToBody(&body_strvec, "requested_token_type", + requested_token_type_.get()); + if (actor_token_path_ != nullptr) { + err = LoadTokenFile(actor_token_path_.get(), &actor_token); + if (err != GRPC_ERROR_NONE) return cleanup(); + MaybeAddToBody( + &body_strvec, "actor_token", + reinterpret_cast(GRPC_SLICE_START_PTR(subject_token))); + MaybeAddToBody(&body_strvec, "actor_token_type", actor_token_type_.get()); + } + return cleanup(); + } + + grpc_uri* sts_url_; + grpc_closure http_post_cb_closure_; + grpc_core::UniquePtr resource_; + grpc_core::UniquePtr audience_; + grpc_core::UniquePtr scope_; + grpc_core::UniquePtr requested_token_type_; + grpc_core::UniquePtr subject_token_path_; + grpc_core::UniquePtr subject_token_type_; + grpc_core::UniquePtr actor_token_path_; + grpc_core::UniquePtr actor_token_type_; +}; + +} // namespace + +grpc_error* ValidateStsCredentialsOptions( + const grpc_sts_credentials_options* options, grpc_uri** sts_url_out) { + struct GrpcUriDeleter { + void operator()(grpc_uri* uri) { grpc_uri_destroy(uri); } + }; + *sts_url_out = nullptr; + InlinedVector error_list; + UniquePtr sts_url( + options->sts_endpoint_url != nullptr + ? grpc_uri_parse(options->sts_endpoint_url, false) + : nullptr); + if (sts_url == nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Invalid or missing STS endpoint URL")); + } else { + if (strcmp(sts_url->scheme, "https") != 0 && + strcmp(sts_url->scheme, "http") != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Invalid URI scheme, must be https to http.")); + } + } + if (options->subject_token_path == nullptr || + strlen(options->subject_token_path) == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "subject_token needs to be specified")); + } + if (options->subject_token_type == nullptr || + strlen(options->subject_token_type) == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "subject_token_type needs to be specified")); + } + if (error_list.empty()) { + *sts_url_out = sts_url.release(); + return GRPC_ERROR_NONE; + } else { + return GRPC_ERROR_CREATE_FROM_VECTOR("Invalid STS Credentials Options", + &error_list); + } +} + +} // namespace grpc_core + +grpc_call_credentials* grpc_sts_credentials_create( + const grpc_sts_credentials_options* options, void* reserved) { + GPR_ASSERT(reserved == nullptr); + grpc_uri* sts_url; + grpc_error* error = + grpc_core::ValidateStsCredentialsOptions(options, &sts_url); + if (error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "STS Credentials creation failed. Error: %s.", + grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + return nullptr; + } + return grpc_core::MakeRefCounted( + sts_url, options) + .release(); +} + // // Oauth2 Access Token credentials. // diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h index 510a78b484a..c9b2d1decac 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h @@ -21,8 +21,15 @@ #include +#include #include "src/core/lib/json/json.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/uri/uri_parser.h" + +// Constants. +#define GRPC_STS_POST_MINIMAL_BODY_FORMAT_STRING \ + "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token=%" \ + "s&subject_token_type=%s" // auth_refresh_token parsing. typedef struct { @@ -115,6 +122,7 @@ class grpc_google_refresh_token_credentials final private: grpc_auth_refresh_token refresh_token_; + grpc_closure http_post_cb_closure_; }; // Access token credentials. @@ -148,4 +156,12 @@ grpc_oauth2_token_fetcher_credentials_parse_server_response( const struct grpc_http_response* response, grpc_mdelem* token_md, grpc_millis* token_lifetime); +namespace grpc_core { +// Exposed for testing only. This function validates the options, ensuring that +// the required fields are set, and outputs the parsed URL of the STS token +// exchanged service. +grpc_error* ValidateStsCredentialsOptions( + const grpc_sts_credentials_options* options, grpc_uri** sts_url); +} // namespace grpc_core + #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */ diff --git a/src/core/lib/security/util/json_util.cc b/src/core/lib/security/util/json_util.cc index fe9f5fe3d35..8a1db636139 100644 --- a/src/core/lib/security/util/json_util.cc +++ b/src/core/lib/security/util/json_util.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/util/json_util.h" #include @@ -26,17 +27,27 @@ #include const char* grpc_json_get_string_property(const grpc_json* json, - const char* prop_name) { - grpc_json* child; + const char* prop_name, + grpc_error** error) { + grpc_json* child = nullptr; + if (error != nullptr) *error = GRPC_ERROR_NONE; for (child = json->child; child != nullptr; child = child->next) { if (child->key == nullptr) { - gpr_log(GPR_ERROR, "Invalid (null) JSON key encountered"); + if (error != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Invalid (null) JSON key encountered"); + } return nullptr; } if (strcmp(child->key, prop_name) == 0) break; } if (child == nullptr || child->type != GRPC_JSON_STRING) { - gpr_log(GPR_ERROR, "Invalid or missing %s property.", prop_name); + if (error != nullptr) { + char* error_msg; + gpr_asprintf(&error_msg, "Invalid or missing %s property.", prop_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + } return nullptr; } return child->value; @@ -45,7 +56,10 @@ const char* grpc_json_get_string_property(const grpc_json* json, bool grpc_copy_json_string_property(const grpc_json* json, const char* prop_name, char** copied_value) { - const char* prop_value = grpc_json_get_string_property(json, prop_name); + grpc_error* error = GRPC_ERROR_NONE; + const char* prop_value = + grpc_json_get_string_property(json, prop_name, &error); + GRPC_LOG_IF_ERROR("Could not copy JSON property", error); if (prop_value == nullptr) return false; *copied_value = gpr_strdup(prop_value); return true; diff --git a/src/core/lib/security/util/json_util.h b/src/core/lib/security/util/json_util.h index 89deffcc081..44d9eccd545 100644 --- a/src/core/lib/security/util/json_util.h +++ b/src/core/lib/security/util/json_util.h @@ -23,6 +23,7 @@ #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/json/json.h" // Constants. @@ -32,7 +33,8 @@ // Gets a child property from a json node. const char* grpc_json_get_string_property(const grpc_json* json, - const char* prop_name); + const char* prop_name, + grpc_error** error); // Copies the value of the json child property specified by prop_name. // Returns false if the property was not found. diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index b1165a6d6eb..fa275c75419 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -134,6 +134,7 @@ grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import; grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import; grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; +grpc_sts_credentials_create_type grpc_sts_credentials_create_import; grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; grpc_secure_channel_create_type grpc_secure_channel_create_import; grpc_server_credentials_release_type grpc_server_credentials_release_import; @@ -404,6 +405,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create"); grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create"); grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create"); + grpc_sts_credentials_create_import = (grpc_sts_credentials_create_type) GetProcAddress(library, "grpc_sts_credentials_create"); grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin"); grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create"); grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 5809194f1ae..1389c301728 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -377,6 +377,9 @@ extern grpc_access_token_credentials_create_type grpc_access_token_credentials_c typedef grpc_call_credentials*(*grpc_google_iam_credentials_create_type)(const char* authorization_token, const char* authority_selector, void* reserved); extern grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; #define grpc_google_iam_credentials_create grpc_google_iam_credentials_create_import +typedef grpc_call_credentials*(*grpc_sts_credentials_create_type)(const grpc_sts_credentials_options* options, void* reserved); +extern grpc_sts_credentials_create_type grpc_sts_credentials_create_import; +#define grpc_sts_credentials_create grpc_sts_credentials_create_import typedef grpc_call_credentials*(*grpc_metadata_credentials_create_from_plugin_type)(grpc_metadata_credentials_plugin plugin, void* reserved); extern grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; #define grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin_import diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 141346bca94..cbce595c354 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -24,8 +24,8 @@ #include #include +#include #include - #include #include #include @@ -34,13 +34,16 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/http/httpcli.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h" #include "src/core/lib/security/credentials/jwt/jwt_credentials.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include "src/core/lib/security/transport/auth_filters.h" +#include "src/core/lib/uri/uri_parser.h" #include "test/core/util/test_config.h" using grpc_core::internal::grpc_flush_cached_google_default_credentials; @@ -99,15 +102,27 @@ static const char valid_oauth2_json_response[] = " \"expires_in\":3599, " " \"token_type\":\"Bearer\"}"; +static const char valid_sts_json_response[] = + "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," + " \"expires_in\":3599, " + " \"issued_token_type\":\"urn:ietf:params:oauth:token-type:access_token\", " + " \"token_type\":\"Bearer\"}"; + static const char test_scope[] = "perm1 perm2"; static const char test_signed_jwt[] = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY0OTRkN2M1YWU2MGRmOTcyNmM4YW" "U0MDcyZTViYTdmZDkwODg2YzcifQ"; +static const char test_signed_jwt_token_type[] = + "urn:ietf:params:oauth:token-type:id_token"; +static const char test_signed_jwt_path_prefix[] = "test_sign_jwt"; static const char test_service_url[] = "https://foo.com/foo.v1"; static const char other_test_service_url[] = "https://bar.com/bar.v1"; +static const char test_sts_endpoint_url[] = + "https://foo.com:5555/v1/token-exchange"; + static const char test_method[] = "ThisIsNotAMethod"; /* -- Global state flags. -- */ @@ -657,11 +672,11 @@ static int refresh_token_httpcli_post_success( return 1; } -static int refresh_token_httpcli_post_failure( - const grpc_httpcli_request* request, const char* body, size_t body_size, - grpc_millis deadline, grpc_closure* on_done, - grpc_httpcli_response* response) { - validate_refresh_token_http_request(request, body, body_size); +static int token_httpcli_post_failure(const grpc_httpcli_request* request, + const char* body, size_t body_size, + grpc_millis deadline, + grpc_closure* on_done, + grpc_httpcli_response* response) { *response = http_response(403, "Not Authorized."); GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return 1; @@ -676,7 +691,7 @@ static void test_refresh_token_creds_success(void) { grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create( test_refresh_token_str, nullptr); - /* First request: http get should be called. */ + /* First request: http put should be called. */ request_metadata_state* state = make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); grpc_httpcli_set_override(httpcli_get_should_not_be_called, @@ -707,10 +722,279 @@ static void test_refresh_token_creds_failure(void) { grpc_call_credentials* creds = grpc_google_refresh_token_credentials_create( test_refresh_token_str, nullptr); grpc_httpcli_set_override(httpcli_get_should_not_be_called, - refresh_token_httpcli_post_failure); + token_httpcli_post_failure); + run_request_metadata_test(creds, auth_md_ctx, state); + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); +} + +static void test_valid_sts_creds_options(void) { + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_uri* sts_url; + grpc_error* error = + grpc_core::ValidateStsCredentialsOptions(&valid_options, &sts_url); + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(sts_url != nullptr); + grpc_core::StringView host; + grpc_core::StringView port; + GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority, &host, &port)); + GPR_ASSERT(host.cmp("foo.com") == 0); + GPR_ASSERT(port.cmp("5555") == 0); + grpc_uri_destroy(sts_url); +} + +static void test_invalid_sts_creds_options(void) { + grpc_sts_credentials_options invalid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + nullptr, // subject_token_path (Required) + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_uri* url_should_be_null; + grpc_error* error = grpc_core::ValidateStsCredentialsOptions( + &invalid_options, &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + test_sts_endpoint_url, // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + nullptr, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + nullptr, // sts_endpoint_url (Required) + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + "not_a_valid_uri", // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); + + invalid_options = { + "ftp://ftp.is.not.a.valid.scheme/bar", // sts_endpoint_url + nullptr, // resource + nullptr, // audience + nullptr, // scope + nullptr, // requested_token_type + test_signed_jwt_path_prefix, // subject_token_path + test_signed_jwt_token_type, // subject_token_type (Required) + nullptr, // actor_token_path + nullptr // actor_token_type + }; + error = grpc_core::ValidateStsCredentialsOptions(&invalid_options, + &url_should_be_null); + GPR_ASSERT(error != GRPC_ERROR_NONE); + GRPC_ERROR_UNREF(error); + GPR_ASSERT(url_should_be_null == nullptr); +} + +static void validate_sts_token_http_request(const grpc_httpcli_request* request, + const char* body, + size_t body_size) { + // Check that the body is constructed properly. + GPR_ASSERT(body != nullptr); + GPR_ASSERT(body_size != 0); + GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl); + char* get_url_equivalent; + gpr_asprintf(&get_url_equivalent, "%s?%s", test_sts_endpoint_url, body); + grpc_uri* url = grpc_uri_parse(get_url_equivalent, false); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "resource"), "resource") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "audience"), "audience") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "scope"), "scope") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "requested_token_type"), + "requested_token_type") == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token"), + test_signed_jwt) == 0); + GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token_type"), + test_signed_jwt_token_type) == 0); + GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token") == nullptr); + GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token_type") == nullptr); + grpc_uri_destroy(url); + gpr_free(get_url_equivalent); + + // Check the rest of the request. + GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0); + GPR_ASSERT(strcmp(request->http.path, "/v1/token-exchange") == 0); + GPR_ASSERT(request->http.hdr_count == 1); + GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0); + GPR_ASSERT(strcmp(request->http.hdrs[0].value, + "application/x-www-form-urlencoded") == 0); +} + +static int sts_token_httpcli_post_success(const grpc_httpcli_request* request, + const char* body, size_t body_size, + grpc_millis deadline, + grpc_closure* on_done, + grpc_httpcli_response* response) { + validate_sts_token_http_request(request, body, body_size); + *response = http_response(200, valid_sts_json_response); + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return 1; +} + +static char* write_tmp_jwt_file(void) { + char* path; + FILE* tmp = gpr_tmpfile(test_signed_jwt_path_prefix, &path); + GPR_ASSERT(path != nullptr); + GPR_ASSERT(tmp != nullptr); + size_t jwt_length = strlen(test_signed_jwt); + GPR_ASSERT(fwrite(test_signed_jwt, 1, jwt_length, tmp) == jwt_length); + fclose(tmp); + return path; +} + +static void test_sts_creds_success(void) { + grpc_core::ExecCtx exec_ctx; + expected_md emd[] = { + {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}}; + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + test_signed_jwt_path, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = + grpc_sts_credentials_create(&valid_options, nullptr); + + /* First request: http put should be called. */ + request_metadata_state* state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + sts_token_httpcli_post_success); + run_request_metadata_test(creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + + /* Second request: the cached token should be served directly. */ + state = + make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd)); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds, auth_md_ctx, state); + grpc_core::ExecCtx::Get()->Flush(); + + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); +} + +static void test_sts_creds_load_token_failure(void) { + grpc_core::ExecCtx exec_ctx; + request_metadata_state* state = make_request_metadata_state( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Error occurred when fetching oauth2 token."), + nullptr, 0); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + "invalid_path", // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = grpc_sts_credentials_create(&options, nullptr); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + httpcli_post_should_not_be_called); + run_request_metadata_test(creds, auth_md_ctx, state); + creds->Unref(); + grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); +} + +static void test_sts_creds_http_failure(void) { + grpc_core::ExecCtx exec_ctx; + request_metadata_state* state = make_request_metadata_state( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Error occurred when fetching oauth2 token."), + nullptr, 0); + grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, + nullptr, nullptr}; + char* test_signed_jwt_path = write_tmp_jwt_file(); + grpc_sts_credentials_options valid_options = { + test_sts_endpoint_url, // sts_endpoint_url + "resource", // resource + "audience", // audience + "scope", // scope + "requested_token_type", // requested_token_type + test_signed_jwt_path, // subject_token_path + test_signed_jwt_token_type, // subject_token_type + nullptr, // actor_token_path + nullptr // actor_token_type + }; + grpc_call_credentials* creds = + grpc_sts_credentials_create(&valid_options, nullptr); + grpc_httpcli_set_override(httpcli_get_should_not_be_called, + token_httpcli_post_failure); run_request_metadata_test(creds, auth_md_ctx, state); creds->Unref(); grpc_httpcli_set_override(nullptr, nullptr); + gpr_free(test_signed_jwt_path); } static void validate_jwt_encode_and_sign_params( @@ -1288,6 +1572,11 @@ int main(int argc, char** argv) { test_compute_engine_creds_failure(); test_refresh_token_creds_success(); test_refresh_token_creds_failure(); + test_valid_sts_creds_options(); + test_invalid_sts_creds_options(); + test_sts_creds_success(); + test_sts_creds_load_token_failure(); + test_sts_creds_http_failure(); test_jwt_creds_lifetime(); test_jwt_creds_success(); test_jwt_creds_signing_failure(); diff --git a/test/core/security/fetch_oauth2.cc b/test/core/security/fetch_oauth2.cc index 82efe682be0..d404368b8b9 100644 --- a/test/core/security/fetch_oauth2.cc +++ b/test/core/security/fetch_oauth2.cc @@ -26,33 +26,82 @@ #include #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/util/json_util.h" #include "test/core/security/oauth2_utils.h" #include "test/core/util/cmdline.h" +static grpc_sts_credentials_options sts_options_from_json(grpc_json* json) { + grpc_sts_credentials_options options; + memset(&options, 0, sizeof(options)); + grpc_error* error = GRPC_ERROR_NONE; + options.sts_endpoint_url = + grpc_json_get_string_property(json, "sts_endpoint_url", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.resource = grpc_json_get_string_property(json, "resource", nullptr); + options.audience = grpc_json_get_string_property(json, "audience", nullptr); + options.scope = grpc_json_get_string_property(json, "scope", nullptr); + options.requested_token_type = + grpc_json_get_string_property(json, "requested_token_type", nullptr); + options.subject_token_path = + grpc_json_get_string_property(json, "subject_token_path", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.subject_token_type = + grpc_json_get_string_property(json, "subject_token_type", &error); + GRPC_LOG_IF_ERROR("STS credentials parsing", error); + options.actor_token_path = + grpc_json_get_string_property(json, "actor_token_path", nullptr); + options.actor_token_type = + grpc_json_get_string_property(json, "actor_token_type", nullptr); + return options; +} + +static grpc_call_credentials* create_sts_creds(const char* json_file_path) { + grpc_slice sts_options_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR( + "load_file", grpc_load_file(json_file_path, 1, &sts_options_slice))); + grpc_json* json = grpc_json_parse_string( + reinterpret_cast(GRPC_SLICE_START_PTR(sts_options_slice))); + if (json == nullptr) { + gpr_log(GPR_ERROR, "Invalid json"); + return nullptr; + } + grpc_sts_credentials_options options = sts_options_from_json(json); + grpc_call_credentials* result = + grpc_sts_credentials_create(&options, nullptr); + grpc_json_destroy(json); + gpr_slice_unref(sts_options_slice); + return result; +} + static grpc_call_credentials* create_refresh_token_creds( const char* json_refresh_token_file_path) { grpc_slice refresh_token; GPR_ASSERT(GRPC_LOG_IF_ERROR( "load_file", grpc_load_file(json_refresh_token_file_path, 1, &refresh_token))); - return grpc_google_refresh_token_credentials_create( + grpc_call_credentials* result = grpc_google_refresh_token_credentials_create( reinterpret_cast GRPC_SLICE_START_PTR(refresh_token), nullptr); + gpr_slice_unref(refresh_token); + return result; } int main(int argc, char** argv) { grpc_call_credentials* creds = nullptr; - char* json_key_file_path = nullptr; + const char* json_sts_options_file_path = nullptr; const char* json_refresh_token_file_path = nullptr; char* token = nullptr; int use_gce = 0; - char* scope = nullptr; gpr_cmdline* cl = gpr_cmdline_create("fetch_oauth2"); gpr_cmdline_add_string(cl, "json_refresh_token", "File path of the json refresh token.", &json_refresh_token_file_path); + gpr_cmdline_add_string(cl, "json_sts_options", + "File path of the json sts options.", + &json_sts_options_file_path); gpr_cmdline_add_flag( cl, "gce", "Get a token from the GCE metadata server (only works in GCE).", @@ -61,18 +110,20 @@ int main(int argc, char** argv) { grpc_init(); - if (json_key_file_path != nullptr && + if (json_sts_options_file_path != nullptr && json_refresh_token_file_path != nullptr) { - gpr_log(GPR_ERROR, - "--json_key and --json_refresh_token are mutually exclusive."); + gpr_log( + GPR_ERROR, + "--json_sts_options and --json_refresh_token are mutually exclusive."); exit(1); } if (use_gce) { - if (json_key_file_path != nullptr || scope != nullptr) { + if (json_sts_options_file_path != nullptr || + json_refresh_token_file_path != nullptr) { gpr_log(GPR_INFO, - "Ignoring json key and scope to get a token from the GCE " - "metadata server."); + "Ignoring json refresh token or sts options to get a token from " + "the GCE metadata server."); } creds = grpc_google_compute_engine_credentials_create(nullptr); if (creds == nullptr) { @@ -88,8 +139,19 @@ int main(int argc, char** argv) { json_refresh_token_file_path); exit(1); } + } else if (json_sts_options_file_path != nullptr) { + creds = create_sts_creds(json_sts_options_file_path); + if (creds == nullptr) { + gpr_log(GPR_ERROR, + "Could not create sts creds. %s does probably not contain a " + "valid json for sts options.", + json_sts_options_file_path); + exit(1); + } } else { - gpr_log(GPR_ERROR, "Missing --gce or --json_refresh_token option."); + gpr_log( + GPR_ERROR, + "Missing --gce, --json_sts_options, or --json_refresh_token option."); exit(1); } GPR_ASSERT(creds != nullptr); diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc index c9e205ab743..b24e7c180e1 100644 --- a/test/core/security/oauth2_utils.cc +++ b/test/core/security/oauth2_utils.cc @@ -63,14 +63,17 @@ static void on_oauth2_response(void* arg, grpc_error* error) { gpr_mu_unlock(request->mu); } -static void do_nothing(void* unused, grpc_error* error) {} +static void destroy_after_shutdown(void* pollset, grpc_error* error) { + grpc_pollset_destroy(reinterpret_cast(pollset)); + gpr_free(pollset); +} char* grpc_test_fetch_oauth2_token_with_credentials( grpc_call_credentials* creds) { oauth2_request request; memset(&request, 0, sizeof(request)); grpc_core::ExecCtx exec_ctx; - grpc_closure do_nothing_closure; + grpc_closure destroy_after_shutdown_closure; grpc_auth_metadata_context null_ctx = {"", "", nullptr, nullptr}; grpc_pollset* pollset = @@ -79,8 +82,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials( request.pops = grpc_polling_entity_create_from_pollset(pollset); request.is_done = false; - GRPC_CLOSURE_INIT(&do_nothing_closure, do_nothing, nullptr, - grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&destroy_after_shutdown_closure, destroy_after_shutdown, + pollset, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&request.closure, on_oauth2_response, &request, grpc_schedule_on_exec_ctx); @@ -107,8 +110,6 @@ char* grpc_test_fetch_oauth2_token_with_credentials( gpr_mu_unlock(request.mu); grpc_pollset_shutdown(grpc_polling_entity_pollset(&request.pops), - &do_nothing_closure); - - gpr_free(grpc_polling_entity_pollset(&request.pops)); + &destroy_after_shutdown_closure); return request.token; } diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 3aaa1e709ee..e537e482936 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -171,6 +171,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create); printf("%lx", (unsigned long) grpc_access_token_credentials_create); printf("%lx", (unsigned long) grpc_google_iam_credentials_create); + printf("%lx", (unsigned long) grpc_sts_credentials_create); printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin); printf("%lx", (unsigned long) grpc_secure_channel_create); printf("%lx", (unsigned long) grpc_server_credentials_release); From 80c177d4c40ef85eb8ec37f9d4bfa030361958e1 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 26 Jun 2019 16:22:13 -0400 Subject: [PATCH 490/676] Revert "Introduce string_view and use it for gpr_split_host_port." --- BUILD | 8 +- BUILD.gn | 8 +- CMakeLists.txt | 44 +---- Makefile | 54 +----- build.yaml | 20 +-- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 6 +- gRPC-Core.podspec | 8 +- grpc.gemspec | 5 +- grpc.gyp | 2 +- package.xml | 5 +- .../ext/filters/client_channel/http_proxy.cc | 19 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 1 + .../client_channel/lb_policy/xds/xds.cc | 1 + .../filters/client_channel/parse_address.cc | 55 +++--- .../resolver/dns/c_ares/dns_resolver_ares.cc | 1 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 95 +++++----- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 1 + .../dns/c_ares/grpc_ares_wrapper_windows.cc | 1 + .../resolver/dns/native/dns_resolver.cc | 1 + .../resolver/fake/fake_resolver.cc | 1 + .../resolver/sockaddr/sockaddr_resolver.cc | 1 + .../transport/chttp2/server/chttp2_server.cc | 1 + .../transport/chttp2/transport/frame_data.cc | 8 +- .../cronet/transport/cronet_transport.cc | 1 + src/core/lib/channel/channelz.cc | 15 +- src/core/lib/gpr/host_port.cc | 98 +++++++++++ src/core/lib/{gprpp => gpr}/host_port.h | 38 ++-- src/core/lib/gpr/string.cc | 9 +- src/core/lib/gpr/string.h | 1 - src/core/lib/gprpp/host_port.cc | 97 ----------- src/core/lib/gprpp/string_view.h | 143 --------------- .../lib/http/httpcli_security_connector.cc | 4 +- src/core/lib/iomgr/resolve_address_custom.cc | 35 ++-- src/core/lib/iomgr/resolve_address_posix.cc | 18 +- src/core/lib/iomgr/resolve_address_windows.cc | 14 +- src/core/lib/iomgr/sockaddr_utils.cc | 8 +- .../lib/iomgr/socket_utils_common_posix.cc | 1 + src/core/lib/iomgr/tcp_client_cfstream.cc | 13 +- .../alts/alts_security_connector.cc | 5 +- .../fake/fake_security_connector.cc | 46 ++--- .../local/local_security_connector.cc | 5 +- .../security_connector/security_connector.cc | 2 +- .../security_connector/security_connector.h | 2 +- .../ssl/ssl_security_connector.cc | 38 ++-- .../security/security_connector/ssl_utils.cc | 57 +++--- .../security/security_connector/ssl_utils.h | 19 +- .../tls/spiffe_security_connector.cc | 36 ++-- .../tls/spiffe_security_connector.h | 7 +- .../security/transport/client_auth_filter.cc | 3 +- .../alts/handshaker/alts_tsi_handshaker.cc | 1 + src/core/tsi/ssl_transport_security.cc | 78 +++++---- src/core/tsi/ssl_transport_security.h | 3 +- .../CronetTests/CoreCronetEnd2EndTests.mm | 21 +-- .../tests/CronetTests/CronetUnitTests.mm | 14 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- test/core/bad_ssl/bad_ssl_test.cc | 8 +- .../parse_address_with_named_scope_id_test.cc | 17 +- test/core/end2end/bad_server_response_test.cc | 11 +- test/core/end2end/connection_refused_test.cc | 12 +- test/core/end2end/dualstack_socket_test.cc | 25 +-- test/core/end2end/fixtures/h2_census.cc | 22 +-- test/core/end2end/fixtures/h2_compress.cc | 33 ++-- test/core/end2end/fixtures/h2_fakesec.cc | 23 +-- test/core/end2end/fixtures/h2_full+pipe.cc | 21 +-- test/core/end2end/fixtures/h2_full+trace.cc | 21 +-- .../end2end/fixtures/h2_full+workarounds.cc | 24 +-- test/core/end2end/fixtures/h2_full.cc | 21 +-- test/core/end2end/fixtures/h2_http_proxy.cc | 27 +-- test/core/end2end/fixtures/h2_local_ipv4.cc | 4 +- test/core/end2end/fixtures/h2_local_ipv6.cc | 4 +- test/core/end2end/fixtures/h2_local_uds.cc | 8 +- test/core/end2end/fixtures/h2_oauth2.cc | 25 +-- test/core/end2end/fixtures/h2_proxy.cc | 1 + test/core/end2end/fixtures/h2_spiffe.cc | 25 ++- test/core/end2end/fixtures/h2_ssl.cc | 22 +-- .../end2end/fixtures/h2_ssl_cred_reload.cc | 24 +-- test/core/end2end/fixtures/h2_ssl_proxy.cc | 1 + test/core/end2end/fixtures/h2_uds.cc | 1 + .../end2end/fixtures/http_proxy_fixture.cc | 14 +- test/core/end2end/fixtures/inproc.cc | 1 + test/core/end2end/fixtures/local_util.cc | 15 +- test/core/end2end/fixtures/local_util.h | 6 +- test/core/end2end/fixtures/proxy.cc | 29 ++-- test/core/end2end/h2_ssl_cert_test.cc | 22 +-- .../core/end2end/h2_ssl_session_reuse_test.cc | 15 +- .../end2end/invalid_call_argument_test.cc | 15 +- test/core/fling/fling_stream_test.cc | 11 +- test/core/fling/fling_test.cc | 12 +- test/core/fling/server.cc | 12 +- test/core/gpr/BUILD | 10 ++ test/core/{gprpp => gpr}/host_port_test.cc | 11 +- test/core/gprpp/BUILD | 23 --- test/core/gprpp/string_view_test.cc | 163 ------------------ test/core/memory_usage/memory_usage_test.cc | 11 +- test/core/memory_usage/server.cc | 12 +- ...num_external_connectivity_watchers_test.cc | 21 ++- .../surface/sequential_connectivity_test.cc | 11 +- test/core/surface/server_chttp2_test.cc | 12 +- test/core/surface/server_test.cc | 14 +- test/core/util/reconnect_server.cc | 1 + test/core/util/test_tcp_server.cc | 1 + test/cpp/interop/interop_test.cc | 1 + test/cpp/naming/address_sorting_test.cc | 18 +- test/cpp/naming/cancel_ares_query_test.cc | 1 + test/cpp/naming/resolver_component_test.cc | 16 +- test/cpp/qps/client_sync.cc | 1 + test/cpp/qps/driver.cc | 22 ++- test/cpp/qps/qps_worker.cc | 9 +- test/cpp/qps/server_async.cc | 9 +- test/cpp/qps/server_callback.cc | 9 +- test/cpp/qps/server_sync.cc | 9 +- tools/doxygen/Doxyfile.c++.internal | 3 +- tools/doxygen/Doxyfile.core.internal | 5 +- .../generated/sources_and_headers.json | 28 +-- tools/run_tests/generated/tests.json | 24 --- 117 files changed, 881 insertions(+), 1280 deletions(-) create mode 100644 src/core/lib/gpr/host_port.cc rename src/core/lib/{gprpp => gpr}/host_port.h (51%) delete mode 100644 src/core/lib/gprpp/host_port.cc delete mode 100644 src/core/lib/gprpp/string_view.h rename test/core/{gprpp => gpr}/host_port_test.cc (86%) delete mode 100644 test/core/gprpp/string_view_test.cc diff --git a/BUILD b/BUILD index 821c3824948..8fd52808400 100644 --- a/BUILD +++ b/BUILD @@ -558,6 +558,7 @@ grpc_cc_library( "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", + "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -584,7 +585,6 @@ grpc_cc_library( "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", - "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -594,6 +594,7 @@ grpc_cc_library( "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", + "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -610,16 +611,14 @@ grpc_cc_library( "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", - "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/host_port.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", "src/core/lib/gprpp/pair.h", - "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", @@ -628,7 +627,6 @@ grpc_cc_library( public_hdrs = GPR_PUBLIC_HDRS, deps = [ "gpr_codegen", - "grpc_codegen", ], ) diff --git a/BUILD.gn b/BUILD.gn index 9ae5b1ed22b..e5396f51426 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -141,6 +141,8 @@ config("grpc_config") { "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", + "src/core/lib/gpr/host_port.cc", + "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -187,8 +189,6 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/host_port.cc", - "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -480,7 +480,6 @@ config("grpc_config") { "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", - "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.cc", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.cc", @@ -1172,6 +1171,7 @@ config("grpc_config") { "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", + "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -1193,7 +1193,6 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/inlined_vector.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", @@ -1203,7 +1202,6 @@ config("grpc_config") { "src/core/lib/gprpp/pair.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", - "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/http/format_request.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 19c8d44b05d..a34f9265256 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -713,7 +713,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx streaming_throughput_test) endif() add_dependencies(buildtests_cxx stress_test) -add_dependencies(buildtests_cxx string_view_test) add_dependencies(buildtests_cxx thread_manager_test) add_dependencies(buildtests_cxx thread_stress_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -862,6 +861,7 @@ add_library(gpr src/core/lib/gpr/env_linux.cc src/core/lib/gpr/env_posix.cc src/core/lib/gpr/env_windows.cc + src/core/lib/gpr/host_port.cc src/core/lib/gpr/log.cc src/core/lib/gpr/log_android.cc src/core/lib/gpr/log_linux.cc @@ -888,7 +888,6 @@ add_library(gpr src/core/lib/gprpp/arena.cc src/core/lib/gprpp/fork.cc src/core/lib/gprpp/global_config_env.cc - src/core/lib/gprpp/host_port.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -7507,7 +7506,7 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(gpr_host_port_test - test/core/gprpp/host_port_test.cc + test/core/gpr/host_port_test.cc ) @@ -16640,45 +16639,6 @@ target_link_libraries(stress_test ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - -add_executable(string_view_test - test/core/gprpp/string_view_test.cc - third_party/googletest/googletest/src/gtest-all.cc - third_party/googletest/googlemock/src/gmock-all.cc -) - - -target_include_directories(string_view_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} - PRIVATE third_party/googletest/googletest/include - PRIVATE third_party/googletest/googletest - PRIVATE third_party/googletest/googlemock/include - PRIVATE third_party/googletest/googlemock - PRIVATE ${_gRPC_PROTO_GENS_DIR} -) - -target_link_libraries(string_view_test - ${_gRPC_PROTOBUF_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc++ - grpc - gpr - ${_gRPC_GFLAGS_LIBRARIES} -) - - endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 2d28e7b5656..9930fc35a25 100644 --- a/Makefile +++ b/Makefile @@ -1278,7 +1278,6 @@ status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test status_util_test: $(BINDIR)/$(CONFIG)/status_util_test streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test -string_view_test: $(BINDIR)/$(CONFIG)/string_view_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test time_change_test: $(BINDIR)/$(CONFIG)/time_change_test @@ -1745,7 +1744,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ - $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -1909,7 +1907,6 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ - $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -2436,8 +2433,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 ) $(E) "[RUN] Testing streaming_throughput_test" $(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 ) - $(E) "[RUN] Testing string_view_test" - $(Q) $(BINDIR)/$(CONFIG)/string_view_test || ( echo test string_view_test failed ; exit 1 ) $(E) "[RUN] Testing thread_manager_test" $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(E) "[RUN] Testing thread_stress_test" @@ -3384,6 +3379,7 @@ LIBGPR_SRC = \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ + src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -3410,7 +3406,6 @@ LIBGPR_SRC = \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ - src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -10223,7 +10218,7 @@ endif GPR_HOST_PORT_TEST_SRC = \ - test/core/gprpp/host_port_test.cc \ + test/core/gpr/host_port_test.cc \ GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -10243,7 +10238,7 @@ $(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(C endif -$(OBJDIR)/$(CONFIG)/test/core/gprpp/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a +$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -19671,49 +19666,6 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc -STRING_VIEW_TEST_SRC = \ - test/core/gprpp/string_view_test.cc \ - -STRING_VIEW_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRING_VIEW_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/string_view_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.5.0+. - -$(BINDIR)/$(CONFIG)/string_view_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/string_view_test: $(PROTOBUF_DEP) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/string_view_test - -endif - -endif - -$(OBJDIR)/$(CONFIG)/test/core/gprpp/string_view_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_string_view_test: $(STRING_VIEW_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(STRING_VIEW_TEST_OBJS:.o=.dep) -endif -endif - - THREAD_MANAGER_TEST_SRC = \ test/cpp/thread_manager/thread_manager_test.cc \ diff --git a/build.yaml b/build.yaml index 41c32396a42..dad2146bd1c 100644 --- a/build.yaml +++ b/build.yaml @@ -122,6 +122,7 @@ filegroups: - src/core/lib/gpr/env_linux.cc - src/core/lib/gpr/env_posix.cc - src/core/lib/gpr/env_windows.cc + - src/core/lib/gpr/host_port.cc - src/core/lib/gpr/log.cc - src/core/lib/gpr/log_android.cc - src/core/lib/gpr/log_linux.cc @@ -148,7 +149,6 @@ filegroups: - src/core/lib/gprpp/arena.cc - src/core/lib/gprpp/fork.cc - src/core/lib/gprpp/global_config_env.cc - - src/core/lib/gprpp/host_port.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -178,6 +178,7 @@ filegroups: - src/core/lib/gpr/alloc.h - src/core/lib/gpr/arena.h - src/core/lib/gpr/env.h + - src/core/lib/gpr/host_port.h - src/core/lib/gpr/mpscq.h - src/core/lib/gpr/murmur_hash.h - src/core/lib/gpr/spinlock.h @@ -198,7 +199,6 @@ filegroups: - src/core/lib/gprpp/global_config_custom.h - src/core/lib/gprpp/global_config_env.h - src/core/lib/gprpp/global_config_generic.h - - src/core/lib/gprpp/host_port.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h @@ -444,7 +444,6 @@ filegroups: - src/core/lib/gprpp/orphanable.h - src/core/lib/gprpp/ref_counted.h - src/core/lib/gprpp/ref_counted_ptr.h - - src/core/lib/gprpp/string_view.h - src/core/lib/http/format_request.h - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h @@ -2626,7 +2625,7 @@ targets: build: test language: c src: - - test/core/gprpp/host_port_test.cc + - test/core/gpr/host_port_test.cc deps: - gpr - grpc_test_util_unsecure @@ -5761,19 +5760,6 @@ targets: - grpc - gpr - grpc++_test_config -- name: string_view_test - gtest: true - build: test - language: c++ - src: - - test/core/gprpp/string_view_test.cc - deps: - - grpc_test_util - - grpc++ - - grpc - - gpr - uses: - - grpc++_test - name: thread_manager_test build: test language: c++ diff --git a/config.m4 b/config.m4 index 99d49d391b4..bb30be56910 100644 --- a/config.m4 +++ b/config.m4 @@ -53,6 +53,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ + src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -79,7 +80,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ - src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ diff --git a/config.w32 b/config.w32 index f6c6b4fde10..c9faa8d9ac8 100644 --- a/config.w32 +++ b/config.w32 @@ -28,6 +28,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gpr\\env_linux.cc " + "src\\core\\lib\\gpr\\env_posix.cc " + "src\\core\\lib\\gpr\\env_windows.cc " + + "src\\core\\lib\\gpr\\host_port.cc " + "src\\core\\lib\\gpr\\log.cc " + "src\\core\\lib\\gpr\\log_android.cc " + "src\\core\\lib\\gpr\\log_linux.cc " + @@ -54,7 +55,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gprpp\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + "src\\core\\lib\\gprpp\\global_config_env.cc " + - "src\\core\\lib\\gprpp\\host_port.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 17b44738cc2..f0a4418b20c 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -261,6 +261,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', + 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -281,7 +282,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', - 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -444,7 +444,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', - 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -592,6 +591,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', + 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -612,7 +612,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', - 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -649,7 +648,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', - 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6255fdfd0ce..2e34e8d7573 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -191,6 +191,7 @@ Pod::Spec.new do |s| ss.source_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', + 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -211,7 +212,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', - 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -228,6 +228,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', + 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -254,7 +255,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', - 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -414,7 +414,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', - 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -885,6 +884,7 @@ Pod::Spec.new do |s| ss.private_header_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', + 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -905,7 +905,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', - 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -1068,7 +1067,6 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', - 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/grpc.gemspec b/grpc.gemspec index a1051fd4685..11469a3ec5c 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -85,6 +85,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/alloc.h ) s.files += %w( src/core/lib/gpr/arena.h ) s.files += %w( src/core/lib/gpr/env.h ) + s.files += %w( src/core/lib/gpr/host_port.h ) s.files += %w( src/core/lib/gpr/mpscq.h ) s.files += %w( src/core/lib/gpr/murmur_hash.h ) s.files += %w( src/core/lib/gpr/spinlock.h ) @@ -105,7 +106,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/global_config_custom.h ) s.files += %w( src/core/lib/gprpp/global_config_env.h ) s.files += %w( src/core/lib/gprpp/global_config_generic.h ) - s.files += %w( src/core/lib/gprpp/host_port.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) @@ -122,6 +122,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/env_linux.cc ) s.files += %w( src/core/lib/gpr/env_posix.cc ) s.files += %w( src/core/lib/gpr/env_windows.cc ) + s.files += %w( src/core/lib/gpr/host_port.cc ) s.files += %w( src/core/lib/gpr/log.cc ) s.files += %w( src/core/lib/gpr/log_android.cc ) s.files += %w( src/core/lib/gpr/log_linux.cc ) @@ -148,7 +149,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) s.files += %w( src/core/lib/gprpp/global_config_env.cc ) - s.files += %w( src/core/lib/gprpp/host_port.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) @@ -348,7 +348,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/orphanable.h ) s.files += %w( src/core/lib/gprpp/ref_counted.h ) s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h ) - s.files += %w( src/core/lib/gprpp/string_view.h ) s.files += %w( src/core/lib/http/format_request.h ) s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) diff --git a/grpc.gyp b/grpc.gyp index 784279301d3..6268bed7bb0 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -226,6 +226,7 @@ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', + 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -252,7 +253,6 @@ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', - 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/package.xml b/package.xml index 388e8d8620a..616e1ece20e 100644 --- a/package.xml +++ b/package.xml @@ -90,6 +90,7 @@ + @@ -110,7 +111,6 @@ - @@ -127,6 +127,7 @@ + @@ -153,7 +154,6 @@ - @@ -353,7 +353,6 @@ - diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc index 9e60a553ceb..8951a2920c4 100644 --- a/src/core/ext/filters/client_channel/http_proxy.cc +++ b/src/core/ext/filters/client_channel/http_proxy.cc @@ -31,8 +31,8 @@ #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/slice/b64.h" #include "src/core/lib/uri/uri_parser.h" @@ -126,18 +126,17 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, if (no_proxy_str != nullptr) { static const char* NO_PROXY_SEPARATOR = ","; bool use_proxy = true; - grpc_core::UniquePtr server_host; - grpc_core::UniquePtr server_port; - if (!grpc_core::SplitHostPort( - uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host, - &server_port)) { + char* server_host; + char* server_port; + if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path, + &server_host, &server_port)) { gpr_log(GPR_INFO, "unable to split host and port, not checking no_proxy list for " "host '%s'", server_uri); gpr_free(no_proxy_str); } else { - size_t uri_len = strlen(server_host.get()); + size_t uri_len = strlen(server_host); char** no_proxy_hosts; size_t num_no_proxy_hosts; gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts, @@ -146,8 +145,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, char* no_proxy_entry = no_proxy_hosts[i]; size_t no_proxy_len = strlen(no_proxy_entry); if (no_proxy_len <= uri_len && - gpr_stricmp(no_proxy_entry, - &(server_host.get()[uri_len - no_proxy_len])) == 0) { + gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) == + 0) { gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'", server_uri); use_proxy = false; @@ -158,6 +157,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, gpr_free(no_proxy_hosts[i]); } gpr_free(no_proxy_hosts); + gpr_free(server_host); + gpr_free(server_port); gpr_free(no_proxy_str); if (!use_proxy) goto no_use_proxy; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 71e8e248770..2f3516066da 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -84,6 +84,7 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index ca9ea9e31cc..e5c27fe67a4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -84,6 +84,7 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/map.h" diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index fbfbb4445f3..c5e1ed811bc 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -33,8 +33,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #ifdef GRPC_POSIX_SOCKET #include @@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - if (!grpc_core::SplitHostPort(hostport, &host, &port)) { + char* host; + char* port; + if (!gpr_split_host_port(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -86,10 +86,8 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, addr->len = static_cast(sizeof(grpc_sockaddr_in)); grpc_sockaddr_in* in = reinterpret_cast(addr->addr); in->sin_family = GRPC_AF_INET; - if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) { - if (log_errors) { - gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get()); - } + if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host); goto done; } // Parse port. @@ -98,14 +96,15 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || - port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get()); + if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port); goto done; } in->sin_port = grpc_htons(static_cast(port_num)); success = true; done: + gpr_free(host); + gpr_free(port); return success; } @@ -125,9 +124,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - if (!grpc_core::SplitHostPort(hostport, &host, &port)) { + char* host; + char* port; + if (!gpr_split_host_port(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -139,12 +138,11 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, grpc_sockaddr_in6* in6 = reinterpret_cast(addr->addr); in6->sin6_family = GRPC_AF_INET6; // Handle the RFC6874 syntax for IPv6 zone identifiers. - char* host_end = - static_cast(gpr_memrchr(host.get(), '%', strlen(host.get()))); + char* host_end = static_cast(gpr_memrchr(host, '%', strlen(host))); if (host_end != nullptr) { - GPR_ASSERT(host_end >= host.get()); + GPR_ASSERT(host_end >= host); char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1]; - size_t host_without_scope_len = static_cast(host_end - host.get()); + size_t host_without_scope_len = static_cast(host_end - host); uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { if (log_errors) { @@ -156,7 +154,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - strncpy(host_without_scope, host.get(), host_without_scope_len); + strncpy(host_without_scope, host, host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { @@ -165,9 +163,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - if (gpr_parse_bytes_to_uint32( - host_end + 1, strlen(host.get()) - host_without_scope_len - 1, - &sin6_scope_id) == 0) { + if (gpr_parse_bytes_to_uint32(host_end + 1, + strlen(host) - host_without_scope_len - 1, + &sin6_scope_id) == 0) { if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { gpr_log(GPR_ERROR, "Invalid interface name: '%s'. " @@ -179,10 +177,8 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; } else { - if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) { - if (log_errors) { - gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get()); - } + if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); goto done; } } @@ -192,14 +188,15 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || - port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get()); + if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); goto done; } in6->sin6_port = grpc_htons(static_cast(port_num)); success = true; done: + gpr_free(host); + gpr_free(port); return success; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index ff15704d692..32a339af359 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -38,6 +38,7 @@ #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 0c1a8ba828f..ad0f1460121 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -35,8 +35,8 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" @@ -355,9 +355,9 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; /* parse name, splitting it into host and port parts */ - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - grpc_core::SplitHostPort(name, &host, &port); + char* host; + char* port; + gpr_split_host_port(name, &host, &port); if (host == nullptr) { error = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -370,7 +370,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto error_cleanup; } - port.reset(gpr_strdup(default_port)); + port = gpr_strdup(default_port); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, query_timeout_ms, combiner, r); @@ -414,22 +414,20 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( } r->pending_queries = 1; if (grpc_ares_query_ipv6()) { - hr = create_hostbyname_request_locked(r, host.get(), - grpc_strhtons(port.get()), - /*is_balancer=*/false); + hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), + false /* is_balancer */); ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked, hr); } - hr = - create_hostbyname_request_locked(r, host.get(), grpc_strhtons(port.get()), - /*is_balancer=*/false); + hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), + false /* is_balancer */); ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked, hr); if (check_grpclb) { /* Query the SRV record */ grpc_ares_request_ref_locked(r); char* service_name; - gpr_asprintf(&service_name, "_grpclb._tcp.%s", host.get()); + gpr_asprintf(&service_name, "_grpclb._tcp.%s", host); ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_locked, r); gpr_free(service_name); @@ -437,25 +435,28 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( if (r->service_config_json_out != nullptr) { grpc_ares_request_ref_locked(r); char* config_name; - gpr_asprintf(&config_name, "_grpc_config.%s", host.get()); + gpr_asprintf(&config_name, "_grpc_config.%s", host); ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked, r); gpr_free(config_name); } grpc_ares_ev_driver_start_locked(r->ev_driver); grpc_ares_request_unref_locked(r); + gpr_free(host); + gpr_free(port); return; error_cleanup: GRPC_CLOSURE_SCHED(r->on_done, error); + gpr_free(host); + gpr_free(port); } static bool inner_resolve_as_ip_literal_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, - grpc_core::UniquePtr* host, grpc_core::UniquePtr* port, - grpc_core::UniquePtr* hostport) { - grpc_core::SplitHostPort(name, host, port); + grpc_core::UniquePtr* addrs, char** host, + char** port, char** hostport) { + gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s to host:port while attempting to resolve as ip " @@ -471,14 +472,12 @@ static bool inner_resolve_as_ip_literal_locked( name); return false; } - port->reset(gpr_strdup(default_port)); + *port = gpr_strdup(default_port); } grpc_resolved_address addr; - GPR_ASSERT(grpc_core::JoinHostPort(hostport, host->get(), atoi(port->get()))); - if (grpc_parse_ipv4_hostport(hostport->get(), &addr, - false /* log errors */) || - grpc_parse_ipv6_hostport(hostport->get(), &addr, - false /* log errors */)) { + GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port))); + if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || + grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); @@ -490,22 +489,24 @@ static bool inner_resolve_as_ip_literal_locked( static bool resolve_as_ip_literal_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - grpc_core::UniquePtr hostport; + char* host = nullptr; + char* port = nullptr; + char* hostport = nullptr; bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs, &host, &port, &hostport); + gpr_free(host); + gpr_free(port); + gpr_free(hostport); return out; } -static bool target_matches_localhost_inner(const char* name, - grpc_core::UniquePtr* host, - grpc_core::UniquePtr* port) { - if (!grpc_core::SplitHostPort(name, host, port)) { +static bool target_matches_localhost_inner(const char* name, char** host, + char** port) { + if (!gpr_split_host_port(name, host, port)) { gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); return false; } - if (gpr_stricmp(host->get(), "localhost") == 0) { + if (gpr_stricmp(*host, "localhost") == 0) { return true; } else { return false; @@ -513,17 +514,20 @@ static bool target_matches_localhost_inner(const char* name, } static bool target_matches_localhost(const char* name) { - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - return target_matches_localhost_inner(name, &host, &port); + char* host = nullptr; + char* port = nullptr; + bool out = target_matches_localhost_inner(name, &host, &port); + gpr_free(host); + gpr_free(port); + return out; } #ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY static bool inner_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, - grpc_core::UniquePtr* host, grpc_core::UniquePtr* port) { - grpc_core::SplitHostPort(name, host, port); + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s into host:port during manual localhost " @@ -539,12 +543,12 @@ static bool inner_maybe_resolve_localhost_manually_locked( name); return false; } - port->reset(gpr_strdup(default_port)); + *port = gpr_strdup(default_port); } - if (gpr_stricmp(host->get(), "localhost") == 0) { + if (gpr_stricmp(*host, "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(port->get()); + uint16_t numeric_port = grpc_strhtons(*port); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); @@ -572,10 +576,13 @@ static bool inner_maybe_resolve_localhost_manually_locked( static bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - return inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; } #else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ static bool grpc_ares_maybe_resolve_localhost_manually_locked( diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index d9e3293deb6..f85feb674dd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -26,6 +26,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" bool grpc_ares_query_ipv6() { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 1749cf77201..06cd5722ce3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -26,6 +26,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index b8434a1cae4..5ab75d02793 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -31,6 +31,7 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index ff728a3dc43..7f613ee21bc 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -32,6 +32,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 517b9297af4..1465b0c644e 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -30,6 +30,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index dc60ec2487b..8285ee76445 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -37,6 +37,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resource_quota.h" diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index c50d7e48d41..74c305b820f 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - p->error = grpc_error_set_str( - p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_slice_from_moved_string(grpc_core::UniquePtr( - grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)))); + p->error = + grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_dump_slice_to_slice( + *slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index a5f6571c510..3ddda268cfb 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -30,6 +30,7 @@ #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/cronet/transport/cronet_transport.h" #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/endpoint.h" diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 184ba17889d..4b130372e46 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -30,9 +30,9 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -406,15 +406,14 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, (strcmp(uri->scheme, "ipv6") == 0))) { const char* host_port = uri->path; if (*host_port == '/') ++host_port; - UniquePtr host; - UniquePtr port; - GPR_ASSERT(SplitHostPort(host_port, &host, &port)); + char* host = nullptr; + char* port = nullptr; + GPR_ASSERT(gpr_split_host_port(host_port, &host, &port)); int port_num = -1; if (port != nullptr) { - port_num = atoi(port.get()); + port_num = atoi(port); } - char* b64_host = - grpc_base64_encode(host.get(), strlen(host.get()), false, false); + char* b64_host = grpc_base64_encode(host, strlen(host), false, false); json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr, GRPC_JSON_OBJECT, false); json = json_iterator; @@ -423,6 +422,8 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, "port", port_num); json_iterator = grpc_json_create_child(json_iterator, json, "ip_address", b64_host, GRPC_JSON_STRING, true); + gpr_free(host); + gpr_free(port); } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) { json_iterator = grpc_json_create_child(json_iterator, json, "uds_address", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/core/lib/gpr/host_port.cc b/src/core/lib/gpr/host_port.cc new file mode 100644 index 00000000000..a34e01cb516 --- /dev/null +++ b/src/core/lib/gpr/host_port.cc @@ -0,0 +1,98 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gpr/host_port.h" + +#include + +#include +#include +#include + +#include "src/core/lib/gpr/string.h" + +int gpr_join_host_port(char** out, const char* host, int port) { + if (host[0] != '[' && strchr(host, ':') != nullptr) { + /* IPv6 literals must be enclosed in brackets. */ + return gpr_asprintf(out, "[%s]:%d", host, port); + } else { + /* Ordinary non-bracketed host:port. */ + return gpr_asprintf(out, "%s:%d", host, port); + } +} + +int gpr_split_host_port(const char* name, char** host, char** port) { + const char* host_start; + size_t host_len; + const char* port_start; + + *host = nullptr; + *port = nullptr; + + if (name[0] == '[') { + /* Parse a bracketed host, typically an IPv6 literal. */ + const char* rbracket = strchr(name, ']'); + if (rbracket == nullptr) { + /* Unmatched [ */ + return 0; + } + if (rbracket[1] == '\0') { + /* ] */ + port_start = nullptr; + } else if (rbracket[1] == ':') { + /* ]: */ + port_start = rbracket + 2; + } else { + /* ] */ + return 0; + } + host_start = name + 1; + host_len = static_cast(rbracket - host_start); + if (memchr(host_start, ':', host_len) == nullptr) { + /* Require all bracketed hosts to contain a colon, because a hostname or + IPv4 address should never use brackets. */ + return 0; + } + } else { + const char* colon = strchr(name, ':'); + if (colon != nullptr && strchr(colon + 1, ':') == nullptr) { + /* Exactly 1 colon. Split into host:port. */ + host_start = name; + host_len = static_cast(colon - name); + port_start = colon + 1; + } else { + /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ + host_start = name; + host_len = strlen(name); + port_start = nullptr; + } + } + + /* Allocate return values. */ + *host = static_cast(gpr_malloc(host_len + 1)); + memcpy(*host, host_start, host_len); + (*host)[host_len] = '\0'; + + if (port_start != nullptr) { + *port = gpr_strdup(port_start); + } + + return 1; +} diff --git a/src/core/lib/gprpp/host_port.h b/src/core/lib/gpr/host_port.h similarity index 51% rename from src/core/lib/gprpp/host_port.h rename to src/core/lib/gpr/host_port.h index 9a0b492b98f..0bf0960f824 100644 --- a/src/core/lib/gprpp/host_port.h +++ b/src/core/lib/gpr/host_port.h @@ -16,44 +16,28 @@ * */ -#ifndef GRPC_CORE_LIB_GPRPP_HOST_PORT_H -#define GRPC_CORE_LIB_GPRPP_HOST_PORT_H +#ifndef GRPC_CORE_LIB_GPR_HOST_PORT_H +#define GRPC_CORE_LIB_GPR_HOST_PORT_H #include -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/string_view.h" - -namespace grpc_core { - /** Given a host and port, creates a newly-allocated string of the form "host:port" or "[ho:st]:port", depending on whether the host contains colons like an IPv6 literal. If the host is already bracketed, then additional brackets will not be added. Usage is similar to gpr_asprintf: returns the number of bytes written - (excluding the final '\0'), and *out points to a string. + (excluding the final '\0'), and *out points to a string which must later be + destroyed using gpr_free(). In the unlikely event of an error, returns -1 and sets *out to NULL. */ -int JoinHostPort(UniquePtr* out, const char* host, int port); +int gpr_join_host_port(char** out, const char* host, int port); /** Given a name in the form "host:port" or "[ho:st]:port", split into hostname - and port number. - - There are two variants of this method: - 1) StringView output: port and host are returned as views on name. - 2) char* output: port and host are copied into newly allocated strings. - - Prefer variant (1) over (2), because no allocation or copy is performed in - variant (1). Use (2) only when interacting with C API that mandate - null-terminated strings. - - Return true on success, false on failure. Guarantees *host and *port are - cleared on failure. */ -bool SplitHostPort(StringView name, StringView* host, StringView* port); -bool SplitHostPort(StringView name, UniquePtr* host, - UniquePtr* port); - -} // namespace grpc_core + and port number, into newly allocated strings, which must later be + destroyed using gpr_free(). + Return 1 on success, 0 on failure. Guarantees *host and *port == NULL on + failure. */ +int gpr_split_host_port(const char* name, char** host, char** port); -#endif /* GRPC_CORE_LIB_GPRPP_HOST_PORT_H */ +#endif /* GRPC_CORE_LIB_GPR_HOST_PORT_H */ diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index 14436ec1bf9..a39f56ef926 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -289,22 +289,17 @@ char* gpr_strvec_flatten(gpr_strvec* sv, size_t* final_length) { return gpr_strjoin((const char**)sv->strs, sv->count, final_length); } -int gpr_strincmp(const char* a, const char* b, size_t n) { +int gpr_stricmp(const char* a, const char* b) { int ca, cb; do { ca = tolower(*a); cb = tolower(*b); ++a; ++b; - --n; - } while (ca == cb && ca != 0 && cb != 0 && n != 0); + } while (ca == cb && ca && cb); return ca - cb; } -int gpr_stricmp(const char* a, const char* b) { - return gpr_strincmp(a, b, SIZE_MAX); -} - static void add_string_to_split(const char* beg, const char* end, char*** strs, size_t* nstrs, size_t* capstrs) { char* out = diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index fcccf5e6764..bf59db7abfe 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -115,7 +115,6 @@ 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); -int gpr_strincmp(const char* a, const char* b, size_t n); void* gpr_memrchr(const void* s, int c, size_t n); diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc deleted file mode 100644 index f3f8a73602a..00000000000 --- a/src/core/lib/gprpp/host_port.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/gprpp/host_port.h" - -#include - -#include -#include -#include - -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/string_view.h" - -namespace grpc_core { -int JoinHostPort(UniquePtr* out, const char* host, int port) { - char* tmp; - int ret; - if (host[0] != '[' && strchr(host, ':') != nullptr) { - /* IPv6 literals must be enclosed in brackets. */ - ret = gpr_asprintf(&tmp, "[%s]:%d", host, port); - } else { - /* Ordinary non-bracketed host:port. */ - ret = gpr_asprintf(&tmp, "%s:%d", host, port); - } - out->reset(tmp); - return ret; -} - -bool SplitHostPort(StringView name, StringView* host, StringView* port) { - if (name[0] == '[') { - /* Parse a bracketed host, typically an IPv6 literal. */ - const size_t rbracket = name.find(']', 1); - if (rbracket == grpc_core::StringView::npos) { - /* Unmatched [ */ - return false; - } - if (rbracket == name.size() - 1) { - /* ] */ - port->clear(); - } else if (name[rbracket + 1] == ':') { - /* ]: */ - *port = name.substr(rbracket + 2, name.size() - rbracket - 2); - } else { - /* ] */ - return false; - } - *host = name.substr(1, rbracket - 1); - if (host->find(':') == grpc_core::StringView::npos) { - /* Require all bracketed hosts to contain a colon, because a hostname or - IPv4 address should never use brackets. */ - host->clear(); - return false; - } - } else { - size_t colon = name.find(':'); - if (colon != grpc_core::StringView::npos && - name.find(':', colon + 1) == grpc_core::StringView::npos) { - /* Exactly 1 colon. Split into host:port. */ - *host = name.substr(0, colon); - *port = name.substr(colon + 1, name.size() - colon - 1); - } else { - /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ - *host = name; - port->clear(); - } - } - return true; -} - -bool SplitHostPort(StringView name, UniquePtr* host, - UniquePtr* port) { - StringView host_view; - StringView port_view; - const bool ret = SplitHostPort(name, &host_view, &port_view); - host->reset(host_view.empty() ? nullptr : host_view.dup().release()); - port->reset(port_view.empty() ? nullptr : port_view.dup().release()); - return ret; -} -} // namespace grpc_core diff --git a/src/core/lib/gprpp/string_view.h b/src/core/lib/gprpp/string_view.h deleted file mode 100644 index 05a81066d48..00000000000 --- a/src/core/lib/gprpp/string_view.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef GRPC_CORE_LIB_GPRPP_STRING_VIEW_H -#define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/memory.h" - -namespace grpc_core { - -// Provides a light-weight view over a char array or a slice, similar but not -// identical to absl::string_view. -// -// Any method that has the same name as absl::string_view MUST HAVE identical -// semantics to what absl::string_view provides. -// -// Methods that are not part of absl::string_view API, must be clearly -// annotated. -// -// StringView does not own the buffers that back the view. Callers must ensure -// the buffer stays around while the StringView is accessible. -// -// Pass StringView by value in functions, since it is exactly two pointers in -// size. -// -// The interface used here is not identical to absl::string_view. Notably, we -// need to support slices while we cannot support std::string, and gpr string -// style functions such as strdup() and cmp(). Once we switch to -// absl::string_view this class will inherit from absl::string_view and add the -// gRPC-specific APIs. -class StringView final { - public: - static constexpr size_t npos = std::numeric_limits::max(); - - constexpr StringView(const char* ptr, size_t size) : ptr_(ptr), size_(size) {} - constexpr StringView(const char* ptr) - : StringView(ptr, ptr == nullptr ? 0 : strlen(ptr)) {} - // Not part of absl::string_view API. - StringView(const grpc_slice& slice) - : StringView(reinterpret_cast(GRPC_SLICE_START_PTR(slice)), - GRPC_SLICE_LENGTH(slice)) {} - constexpr StringView() : StringView(nullptr, 0) {} - - constexpr const char* data() const { return ptr_; } - constexpr size_t size() const { return size_; } - constexpr bool empty() const { return size_ == 0; } - - StringView substr(size_t start, size_t size = npos) { - GPR_DEBUG_ASSERT(start + size <= size_); - return StringView(ptr_ + start, std::min(size, size_ - start)); - } - - constexpr const char& operator[](size_t i) const { return ptr_[i]; } - - const char& front() const { return ptr_[0]; } - const char& back() const { return ptr_[size_ - 1]; } - - void remove_prefix(size_t n) { - GPR_DEBUG_ASSERT(n <= size_); - ptr_ += n; - size_ -= n; - } - - void remove_suffix(size_t n) { - GPR_DEBUG_ASSERT(n <= size_); - size_ -= n; - } - - size_t find(char c, size_t pos = 0) const { - if (empty() || pos >= size_) return npos; - const char* result = - static_cast(memchr(ptr_ + pos, c, size_ - pos)); - return result != nullptr ? result - ptr_ : npos; - } - - void clear() { - ptr_ = nullptr; - size_ = 0; - } - - // Creates a dup of the string viewed by this class. - // Return value is null-terminated and never nullptr. - // - // Not part of absl::string_view API. - grpc_core::UniquePtr dup() const { - char* str = static_cast(gpr_malloc(size_ + 1)); - if (size_ > 0) memcpy(str, ptr_, size_); - str[size_] = '\0'; - return grpc_core::UniquePtr(str); - } - - // Not part of absl::string_view API. - int cmp(StringView other) const { - const size_t len = GPR_MIN(size(), other.size()); - const int ret = strncmp(data(), other.data(), len); - if (ret != 0) return ret; - if (size() == other.size()) return 0; - if (size() < other.size()) return -1; - return 1; - } - - private: - const char* ptr_; - size_t size_; -}; - -inline bool operator==(StringView lhs, StringView rhs) { - return lhs.size() == rhs.size() && - strncmp(lhs.data(), rhs.data(), lhs.size()) == 0; -} - -inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); } - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 8196019f098..762cbe41bcf 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,7 +30,6 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -109,8 +108,7 @@ class grpc_httpcli_ssl_channel_security_connector final return strcmp(secure_peer_name_, other->secure_peer_name_); } - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { *error = GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/resolve_address_custom.cc b/src/core/lib/iomgr/resolve_address_custom.cc index 64c33cdc0d4..9cf7817f66e 100644 --- a/src/core/lib/iomgr/resolve_address_custom.cc +++ b/src/core/lib/iomgr/resolve_address_custom.cc @@ -24,9 +24,9 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address_custom.h" @@ -86,12 +86,11 @@ void grpc_custom_resolve_callback(grpc_custom_resolver* r, } static grpc_error* try_split_host_port(const char* name, - const char* default_port, - grpc_core::UniquePtr* host, - grpc_core::UniquePtr* port) { + const char* default_port, char** host, + char** port) { /* parse name, splitting it into host and port parts */ grpc_error* error; - SplitHostPort(name, host, port); + gpr_split_host_port(name, host, port); if (*host == nullptr) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -108,7 +107,7 @@ static grpc_error* try_split_host_port(const char* name, gpr_free(msg); return error; } - port->reset(gpr_strdup(default_port)); + *port = gpr_strdup(default_port); } return GRPC_ERROR_NONE; } @@ -116,26 +115,28 @@ static grpc_error* try_split_host_port(const char* name, static grpc_error* blocking_resolve_address_impl( const char* name, const char* default_port, grpc_resolved_addresses** addresses) { - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; + char* host; + char* port; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { + gpr_free(host); + gpr_free(port); return err; } /* Call getaddrinfo */ grpc_custom_resolver resolver; - resolver.host = host.get(); - resolver.port = port.get(); + resolver.host = host; + resolver.port = port; grpc_resolved_addresses* addrs; grpc_core::ExecCtx* curr = grpc_core::ExecCtx::Get(); grpc_core::ExecCtx::Set(nullptr); - err = resolve_address_vtable->resolve(host.get(), port.get(), &addrs); + err = resolve_address_vtable->resolve(host, port, &addrs); if (err != GRPC_ERROR_NONE) { if (retry_named_port_failure(&resolver, &addrs)) { GRPC_ERROR_UNREF(err); @@ -146,6 +147,8 @@ static grpc_error* blocking_resolve_address_impl( if (err == GRPC_ERROR_NONE) { *addresses = addrs; } + gpr_free(resolver.host); + gpr_free(resolver.port); return err; } @@ -154,20 +157,22 @@ static void resolve_address_impl(const char* name, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_custom_resolver* r = nullptr; - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; + char* host = nullptr; + char* port = nullptr; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_done, err); + gpr_free(host); + gpr_free(port); return; } r = (grpc_custom_resolver*)gpr_malloc(sizeof(grpc_custom_resolver)); r->on_done = on_done; r->addresses = addrs; - r->host = host.release(); - r->port = port.release(); + r->host = host; + r->port = port; /* Call getaddrinfo */ resolve_address_vtable->resolve_async(r, r->host, r->port); diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index e02dc19bb27..e6dd8f1ceab 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -33,9 +33,9 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -48,6 +48,8 @@ static grpc_error* posix_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = nullptr, *resp; + char* host; + char* port; int s; size_t i; grpc_error* err; @@ -57,10 +59,8 @@ static grpc_error* posix_blocking_resolve_address( return grpc_resolve_unix_domain_address(name + 5, addresses); } - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; /* parse name, splitting it into host and port parts */ - grpc_core::SplitHostPort(name, &host, &port); + gpr_split_host_port(name, &host, &port); if (host == nullptr) { err = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -74,7 +74,7 @@ static grpc_error* posix_blocking_resolve_address( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto done; } - port.reset(gpr_strdup(default_port)); + port = gpr_strdup(default_port); } /* Call getaddrinfo */ @@ -84,16 +84,16 @@ static grpc_error* posix_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host.get(), port.get(), &hints, &result); + s = getaddrinfo(host, port, &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { /* Retry if well-known service name is recognized */ const char* svc[][2] = {{"http", "80"}, {"https", "443"}}; for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { - if (strcmp(port.get(), svc[i][0]) == 0) { + if (strcmp(port, svc[i][0]) == 0) { GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host.get(), svc[i][1], &hints, &result); + s = getaddrinfo(host, svc[i][1], &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; break; } @@ -133,6 +133,8 @@ static grpc_error* posix_blocking_resolve_address( err = GRPC_ERROR_NONE; done: + gpr_free(host); + gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index a06d5cefbcb..64351c38a8f 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -35,8 +35,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -57,14 +57,14 @@ static grpc_error* windows_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = NULL, *resp; + char* host; + char* port; int s; size_t i; grpc_error* error = GRPC_ERROR_NONE; /* parse name, splitting it into host and port parts */ - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - grpc_core::SplitHostPort(name, &host, &port); + gpr_split_host_port(name, &host, &port); if (host == NULL) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -80,7 +80,7 @@ static grpc_error* windows_blocking_resolve_address( gpr_free(msg); goto done; } - port.reset(gpr_strdup(default_port)); + port = gpr_strdup(default_port); } /* Call getaddrinfo */ @@ -90,7 +90,7 @@ static grpc_error* windows_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host.get(), port.get(), &hints, &result); + s = getaddrinfo(host, port, &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { error = GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo"); @@ -122,6 +122,8 @@ static grpc_error* windows_blocking_resolve_address( } done: + gpr_free(host); + gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index baadf1da99e..0839bdfef2d 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -28,8 +28,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" @@ -181,17 +181,15 @@ int grpc_sockaddr_to_string(char** out, } if (ip != nullptr && grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != nullptr) { - grpc_core::UniquePtr tmp_out; if (sin6_scope_id != 0) { char* host_with_scope; /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */ gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id); - ret = grpc_core::JoinHostPort(&tmp_out, host_with_scope, port); + ret = gpr_join_host_port(out, host_with_scope, port); gpr_free(host_with_scope); } else { - ret = grpc_core::JoinHostPort(&tmp_out, ntop_buf, port); + ret = gpr_join_host_port(out, ntop_buf, port); } - *out = tmp_out.release(); } else { ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); } diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 47d9f51b095..2101651b33f 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -46,6 +46,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index fcad5edd222..4b21322d746 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -34,7 +34,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/cfstream_handle.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint_cfstream.h" @@ -143,13 +143,12 @@ static void OnOpen(void* arg, grpc_error* error) { static void ParseResolvedAddress(const grpc_resolved_address* addr, CFStringRef* host, int* port) { - char* host_port; + char *host_port, *host_string, *port_string; grpc_sockaddr_to_string(&host_port, addr, 1); - grpc_core::UniquePtr host_string; - grpc_core::UniquePtr port_string; - grpc_core::SplitHostPort(host_port, &host_string, &port_string); - *host = - CFStringCreateWithCString(NULL, host_string.get(), kCFStringEncodingUTF8); + gpr_split_host_port(host_port, &host_string, &port_string); + *host = CFStringCreateWithCString(NULL, host_string, kCFStringEncodingUTF8); + gpr_free(host_string); + gpr_free(port_string); gpr_free(host_port); *port = grpc_sockaddr_get_port(addr); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 79908601130..38b1f856d52 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -108,11 +108,10 @@ class grpc_alts_channel_security_connector final return strcmp(target_name_, other->target_name_); } - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host.empty() || host != target_name_) { + if (host == nullptr || strcmp(host, target_name_) != 0) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "ALTS call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index 940c2ac5ee5..c55fd34d0e2 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -31,8 +31,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -102,35 +102,39 @@ class grpc_fake_channel_security_connector final tsi_create_fake_handshaker(/*is_client=*/true), this)); } - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - grpc_core::StringView authority_hostname; - grpc_core::StringView authority_ignored_port; - grpc_core::StringView target_hostname; - grpc_core::StringView target_ignored_port; - grpc_core::SplitHostPort(host, &authority_hostname, - &authority_ignored_port); - grpc_core::SplitHostPort(target_, &target_hostname, &target_ignored_port); + char* authority_hostname = nullptr; + char* authority_ignored_port = nullptr; + char* target_hostname = nullptr; + char* target_ignored_port = nullptr; + gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); + gpr_split_host_port(target_, &target_hostname, &target_ignored_port); if (target_name_override_ != nullptr) { - grpc_core::StringView fake_security_target_name_override_hostname; - grpc_core::StringView fake_security_target_name_override_ignored_port; - grpc_core::SplitHostPort( - target_name_override_, &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (authority_hostname != fake_security_target_name_override_hostname) { + char* fake_security_target_name_override_hostname = nullptr; + char* fake_security_target_name_override_ignored_port = nullptr; + gpr_split_host_port(target_name_override_, + &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (strcmp(authority_hostname, + fake_security_target_name_override_hostname) != 0) { gpr_log(GPR_ERROR, "Authority (host) '%s' != Fake Security Target override '%s'", - host.data(), - fake_security_target_name_override_hostname.data()); + host, fake_security_target_name_override_hostname); abort(); } - } else if (authority_hostname != target_hostname) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", host.data(), - target_); + gpr_free(fake_security_target_name_override_hostname); + gpr_free(fake_security_target_name_override_ignored_port); + } else if (strcmp(authority_hostname, target_hostname) != 0) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", + authority_hostname, target_hostname); abort(); } + gpr_free(authority_hostname); + gpr_free(authority_ignored_port); + gpr_free(target_hostname); + gpr_free(target_ignored_port); return true; } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 5b777009d34..c1a101d4ab8 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -156,11 +156,10 @@ class grpc_local_channel_security_connector final creds->connect_type()); } - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host.empty() || host != target_name_) { + if (host == nullptr || strcmp(host, target_name_) != 0) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "local call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 2c7c982e719..47c0ad5aa3d 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index e5ced44638b..f71ee54402d 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -98,7 +98,7 @@ class grpc_channel_security_connector : public grpc_security_connector { /// Returns true if completed synchronously, in which case \a error will /// be set to indicate the result. Otherwise, \a on_call_host_checked /// will be invoked when complete. - virtual bool check_call_host(grpc_core::StringView host, + virtual bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) GRPC_ABSTRACT; diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 97c04cafce4..f920dc6046d 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -75,14 +75,15 @@ class grpc_ssl_channel_security_connector final ? nullptr : gpr_strdup(overridden_target_name)), verify_options_(&config->verify_options) { - grpc_core::StringView host; - grpc_core::StringView port; - grpc_core::SplitHostPort(target_name, &host, &port); - target_name_ = host.dup(); + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); } ~grpc_ssl_channel_security_connector() override { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + if (target_name_ != nullptr) gpr_free(target_name_); + if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); } grpc_security_status InitializeHandshakerFactory( @@ -122,8 +123,8 @@ class grpc_ssl_channel_security_connector final tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_.get() - : target_name_.get(), + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -138,8 +139,8 @@ class grpc_ssl_channel_security_connector final grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_.get() - : target_name_.get(); + ? overridden_target_name_ + : target_name_; grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); if (error == GRPC_ERROR_NONE && verify_options_->verify_peer_callback != nullptr) { @@ -174,18 +175,17 @@ class grpc_ssl_channel_security_connector final reinterpret_cast(other_sc); int c = channel_security_connector_cmp(other); if (c != 0) return c; - c = strcmp(target_name_.get(), other->target_name_.get()); + c = strcmp(target_name_, other->target_name_); if (c != 0) return c; return (overridden_target_name_ == nullptr || other->overridden_target_name_ == nullptr) - ? GPR_ICMP(overridden_target_name_.get(), - other->overridden_target_name_.get()) - : strcmp(overridden_target_name_.get(), - other->overridden_target_name_.get()); + ? GPR_ICMP(overridden_target_name_, + other->overridden_target_name_) + : strcmp(overridden_target_name_, + other->overridden_target_name_); } - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { grpc_security_status status = GRPC_SECURITY_ERROR; @@ -194,7 +194,7 @@ class grpc_ssl_channel_security_connector final /* If the target name was overridden, then the original target_name was 'checked' transitively during the previous peer check at the end of the handshake. */ - if (overridden_target_name_ != nullptr && host == target_name_.get()) { + if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -212,8 +212,8 @@ class grpc_ssl_channel_security_connector final private: tsi_ssl_client_handshaker_factory* client_handshaker_factory_; - grpc_core::UniquePtr target_name_; - grpc_core::UniquePtr overridden_target_name_; + char* target_name_; + char* overridden_target_name_; const verify_peer_options* verify_options_; }; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index ebb4a3f9ee8..cb0d5437988 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,9 +27,9 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" @@ -136,13 +136,12 @@ grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { return GRPC_ERROR_NONE; } -grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, const tsi_peer* peer) { /* Check the peer name if specified. */ - if (!peer_name.empty() && !grpc_ssl_host_matches_name(peer, peer_name)) { + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", - peer_name.data()); + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; @@ -150,16 +149,15 @@ grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, return GRPC_ERROR_NONE; } -bool grpc_ssl_check_call_host(grpc_core::StringView host, - grpc_core::StringView target_name, - grpc_core::StringView overridden_target_name, +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { grpc_security_status status = GRPC_SECURITY_ERROR; tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - if (!overridden_target_name.empty() && host == target_name) { + if (overridden_target_name != nullptr && strcmp(host, target_name) == 0) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -181,28 +179,35 @@ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { return alpn_protocol_strings; } -int grpc_ssl_host_matches_name(const tsi_peer* peer, - grpc_core::StringView peer_name) { - grpc_core::StringView allocated_name; - grpc_core::StringView ignored_port; - grpc_core::SplitHostPort(peer_name, &allocated_name, &ignored_port); - if (allocated_name.empty()) return 0; +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { + char* allocated_name = nullptr; + int r; + + char* ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; // IPv6 zone-id should not be included in comparisons. - const size_t zone_id = allocated_name.find('%'); - if (zone_id != grpc_core::StringView::npos) { - allocated_name.remove_suffix(allocated_name.size() - zone_id); - } - return tsi_ssl_peer_matches_name(peer, allocated_name); + char* const zone_id = strchr(allocated_name, '%'); + if (zone_id != nullptr) *zone_id = '\0'; + + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; } -int grpc_ssl_cmp_target_name( - grpc_core::StringView target_name, grpc_core::StringView other_target_name, - grpc_core::StringView overridden_target_name, - grpc_core::StringView other_overridden_target_name) { - int c = target_name.cmp(other_target_name); +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name) { + int c = strcmp(target_name, other_target_name); if (c != 0) return c; - return overridden_target_name.cmp(other_overridden_target_name); + return (overridden_target_name == nullptr || + other_overridden_target_name == nullptr) + ? GPR_ICMP(overridden_target_name, other_overridden_target_name) + : strcmp(overridden_target_name, other_overridden_target_name); } grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index bf8c1de3aae..1765a344c2a 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -28,7 +28,6 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/ssl_transport_security.h" @@ -47,17 +46,16 @@ GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer); /* Check peer name information returned from SSL handshakes. */ -grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, const tsi_peer* peer); /* Compare targer_name information extracted from SSL security connectors. */ -int grpc_ssl_cmp_target_name( - grpc_core::StringView target_name, grpc_core::StringView other_target_name, - grpc_core::StringView overridden_target_name, - grpc_core::StringView other_overridden_target_name); +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name); /* Check the host that will be set for a call is acceptable.*/ -bool grpc_ssl_check_call_host(grpc_core::StringView host, - grpc_core::StringView target_name, - grpc_core::StringView overridden_target_name, +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error); @@ -91,8 +89,7 @@ grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( tsi_peer grpc_shallow_peer_from_ssl_auth_context( const grpc_auth_context* auth_context); void grpc_shallow_peer_destruct(tsi_peer* peer); -int grpc_ssl_host_matches_name(const tsi_peer* peer, - grpc_core::StringView peer_name); +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); /* --- Default SSL Root Store. --- */ namespace grpc_core { diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc index 5853de4fc13..ebf9c905079 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -28,7 +28,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" #include "src/core/lib/security/credentials/tls/spiffe_credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -105,13 +105,18 @@ SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( ? nullptr : gpr_strdup(overridden_target_name)) { check_arg_ = ServerAuthorizationCheckArgCreate(this); - grpc_core::StringView host; - grpc_core::StringView port; - grpc_core::SplitHostPort(target_name, &host, &port); - target_name_ = host.dup(); + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); } SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { + if (target_name_ != nullptr) { + gpr_free(target_name_); + } + if (overridden_target_name_ != nullptr) { + gpr_free(overridden_target_name_); + } if (client_handshaker_factory_ != nullptr) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); } @@ -125,8 +130,8 @@ void SpiffeChannelSecurityConnector::add_handshakers( tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_.get() - : target_name_.get(), + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -142,8 +147,8 @@ void SpiffeChannelSecurityConnector::check_peer( grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_.get() - : target_name_.get(); + ? overridden_target_name_ + : target_name_; grpc_error* error = grpc_ssl_check_alpn(&peer); if (error != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_peer_checked, error); @@ -198,17 +203,16 @@ int SpiffeChannelSecurityConnector::cmp( if (c != 0) { return c; } - return grpc_ssl_cmp_target_name(target_name_.get(), other->target_name_.get(), - overridden_target_name_.get(), - other->overridden_target_name_.get()); + return grpc_ssl_cmp_target_name(target_name_, other->target_name_, + overridden_target_name_, + other->overridden_target_name_); } bool SpiffeChannelSecurityConnector::check_call_host( - grpc_core::StringView host, grpc_auth_context* auth_context, + const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { - return grpc_ssl_check_call_host(host, target_name_.get(), - overridden_target_name_.get(), auth_context, - on_call_host_checked, error); + return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, + auth_context, on_call_host_checked, error); } void SpiffeChannelSecurityConnector::cancel_check_call_host( diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h index 5ea00ee85b6..56972153e07 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -53,8 +53,7 @@ class SpiffeChannelSecurityConnector final int cmp(const grpc_security_connector* other_sc) const override; - bool check_call_host(grpc_core::StringView host, - grpc_auth_context* auth_context, + bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override; @@ -84,8 +83,8 @@ class SpiffeChannelSecurityConnector final grpc_tls_server_authorization_check_arg* arg); grpc_closure* on_peer_checked_; - grpc_core::UniquePtr target_name_; - grpc_core::UniquePtr overridden_target_name_; + char* target_name_; + char* overridden_target_name_; tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; grpc_tls_server_authorization_check_arg* check_arg_; }; diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 33343d276eb..1062fc2f4fa 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -346,7 +346,7 @@ static void auth_start_transport_stream_op_batch( GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch, grpc_schedule_on_exec_ctx); - grpc_core::StringView call_host(calld->host); + char* call_host = grpc_slice_to_c_string(calld->host); grpc_error* error = GRPC_ERROR_NONE; if (chand->security_connector->check_call_host( call_host, chand->auth_context.get(), @@ -360,6 +360,7 @@ static void auth_start_transport_stream_op_batch( &calld->check_call_host_cancel_closure, cancel_check_call_host, elem, grpc_schedule_on_exec_ctx)); } + gpr_free(call_host); return; /* early exit */ } } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 0d28303e7dd..1b7e58d3ce0 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -30,6 +30,7 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index d3c8982c847..25ae2cee285 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -233,10 +233,11 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) { /* Returns 1 if name looks like an IP address, 0 otherwise. This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ -static int looks_like_ip_address(grpc_core::StringView name) { +static int looks_like_ip_address(const char* name) { + size_t i; size_t dot_count = 0; size_t num_size = 0; - for (size_t i = 0; i < name.size(); ++i) { + for (i = 0; i < strlen(name); i++) { if (name[i] == ':') { /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ return 1; @@ -1505,46 +1506,52 @@ static void tsi_ssl_server_handshaker_factory_destroy( gpr_free(self); } -static int does_entry_match_name(grpc_core::StringView entry, - grpc_core::StringView name) { - if (entry.empty()) return 0; +static int does_entry_match_name(const char* entry, size_t entry_length, + const char* name) { + const char* dot; + const char* name_subdomain = nullptr; + size_t name_length = strlen(name); + size_t name_subdomain_length; + if (entry_length == 0) return 0; /* Take care of '.' terminations. */ - if (name.back() == '.') { - name.remove_suffix(1); + if (name[name_length - 1] == '.') { + name_length--; } - if (entry.back() == '.') { - entry.remove_suffix(1); - if (entry.empty()) return 0; + if (entry[entry_length - 1] == '.') { + entry_length--; + if (entry_length == 0) return 0; } - if (name == entry) { + if ((name_length == entry_length) && + strncmp(name, entry, entry_length) == 0) { return 1; /* Perfect match. */ } - if (entry.front() != '*') return 0; + if (entry[0] != '*') return 0; /* Wildchar subdomain matching. */ - if (entry.size() < 3 || entry[1] != '.') { /* At least *.x */ + if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ gpr_log(GPR_ERROR, "Invalid wildchar entry."); return 0; } - size_t name_subdomain_pos = name.find('.'); - if (name_subdomain_pos == grpc_core::StringView::npos) return 0; - if (name_subdomain_pos >= name.size() - 2) return 0; - grpc_core::StringView name_subdomain = - name.substr(name_subdomain_pos + 1); /* Starts after the dot. */ - entry.remove_prefix(2); /* Remove *. */ - size_t dot = name_subdomain.find('.'); - if (dot == grpc_core::StringView::npos || dot == name_subdomain.size() - 1) { - grpc_core::UniquePtr name_subdomain_cstr(name_subdomain.dup()); - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", - name_subdomain_cstr.get()); + name_subdomain = strchr(name, '.'); + if (name_subdomain == nullptr) return 0; + name_subdomain_length = strlen(name_subdomain); + if (name_subdomain_length < 2) return 0; + name_subdomain++; /* Starts after the dot. */ + name_subdomain_length--; + entry += 2; /* Remove *. */ + entry_length -= 2; + dot = strchr(name_subdomain, '.'); + if ((dot == nullptr) || (dot == &name_subdomain[name_subdomain_length - 1])) { + gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); return 0; } - if (name_subdomain.back() == '.') { - name_subdomain.remove_suffix(1); + if (name_subdomain[name_subdomain_length - 1] == '.') { + name_subdomain_length--; } - return !entry.empty() && name_subdomain == entry; + return ((entry_length > 0) && (name_subdomain_length == entry_length) && + strncmp(entry, name_subdomain, entry_length) == 0); } static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, @@ -1912,8 +1919,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( /* --- tsi_ssl utils. --- */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, - grpc_core::StringView name) { +int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { size_t i = 0; size_t san_count = 0; const tsi_peer_property* cn_property = nullptr; @@ -1927,10 +1933,13 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { san_count++; - grpc_core::StringView entry(property->value.data, property->value.length); - if (!like_ip && does_entry_match_name(entry, name)) { + if (!like_ip && does_entry_match_name(property->value.data, + property->value.length, name)) { return 1; - } else if (like_ip && name == entry) { + } else if (like_ip && + strncmp(name, property->value.data, property->value.length) == + 0 && + strlen(name) == property->value.length) { /* IP Addresses are exact matches only. */ return 1; } @@ -1942,9 +1951,8 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, /* If there's no SAN, try the CN, but only if its not like an IP Address */ if (san_count == 0 && cn_property != nullptr && !like_ip) { - if (does_entry_match_name(grpc_core::StringView(cn_property->value.data, - cn_property->value.length), - name)) { + if (does_entry_match_name(cn_property->value.data, + cn_property->value.length, name)) { return 1; } } diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 0203141e56e..769949e4aad 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -21,7 +21,6 @@ #include -#include "src/core/lib/gprpp/string_view.h" #include "src/core/tsi/transport_security_interface.h" /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ @@ -307,7 +306,7 @@ void tsi_ssl_server_handshaker_factory_unref( - handle mixed case. - handle %encoded chars. - handle public suffix wildchar more strictly (e.g. *.co.uk) */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, grpc_core::StringView name); +int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name); /* --- Testing support. --- diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index ad426014a5b..a24734024dc 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -37,9 +37,9 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -51,18 +51,19 @@ #import "../ConfigureCronet.h" -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_secure_fixture_data { + char *localaddr; +} fullstack_secure_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = grpc_core::New(); + fullstack_secure_fixture_data *ffd = + (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data)); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "127.0.0.1", port); + gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(NULL); @@ -82,8 +83,7 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - f->client = - grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr.get(), client_args, NULL); + f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); GPR_ASSERT(f->client != NULL); } @@ -96,14 +96,15 @@ static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, } f->server = grpc_server_create(server_args, NULL); grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); } static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 4e2e70f1512..2473cf612be 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -33,9 +33,9 @@ #import "src/core/lib/channel/channel_args.h" #import "src/core/lib/gpr/env.h" +#import "src/core/lib/gpr/host_port.h" #import "src/core/lib/gpr/string.h" #import "src/core/lib/gpr/tmpfile.h" -#import "src/core/lib/gprpp/host_port.h" #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" @@ -133,11 +133,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr addr; - grpc_core::JoinHostPort(&addr, "127.0.0.1", port); + char *addr; + gpr_join_host_port(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), NULL, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -264,11 +264,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr addr; - grpc_core::JoinHostPort(&addr, "127.0.0.1", port); + char *addr; + gpr_join_host_port(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), args, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index c7caee551ce..2619ccf9740 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -27,6 +27,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', + 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -53,7 +54,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', - 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index deae9072613..8dd55f64944 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,9 +25,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -145,9 +144,7 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - grpc_core::UniquePtr joined; - grpc_core::JoinHostPort(&joined, "::", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "::", port); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); @@ -156,6 +153,7 @@ int main(int argc, char** argv) { run_test(args[2], i); grpc_shutdown(); } + gpr_free(args[2]); gpr_subprocess_interrupt(svr); status = gpr_subprocess_join(svr); diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc index 071fb88b734..bfafa745178 100644 --- a/test/core/client_channel/parse_address_with_named_scope_id_test.cc +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -30,8 +30,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_config.h" @@ -61,20 +60,20 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo( struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { grpc_uri* uri = grpc_uri_parse(uri_text, 0); - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; - grpc_core::SplitHostPort(uri->path, &host, &port); + char* host = nullptr; + char* port = nullptr; + gpr_split_host_port(uri->path, &host, &port); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; struct addrinfo* result; - int res = getaddrinfo(host.get(), port.get(), &hints, &result); + int res = getaddrinfo(host, port, &hints, &result); if (res != 0) { gpr_log(GPR_ERROR, - "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", - host.get(), port.get(), res); + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, + port, res); abort(); } size_t num_addrs_from_getaddrinfo = 0; @@ -87,6 +86,8 @@ struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { *reinterpret_cast(result->ai_addr); // Cleanup freeaddrinfo(result); + gpr_free(host); + gpr_free(port); grpc_uri_destroy(uri); return out; } diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index db480463b68..2d74b6b77b3 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -29,8 +29,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -71,7 +71,7 @@ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 struct rpc_state { - grpc_core::UniquePtr target; + char* target; grpc_completion_queue* cq; grpc_channel* channel; grpc_call* call; @@ -165,9 +165,8 @@ static void start_rpc(int target_port, grpc_status_code expected_status, state.cq = grpc_completion_queue_create_for_next(nullptr); cqv = cq_verifier_create(state.cq); - grpc_core::JoinHostPort(&state.target, "127.0.0.1", target_port); - state.channel = - grpc_insecure_channel_create(state.target.get(), nullptr, nullptr); + gpr_join_host_port(&state.target, "127.0.0.1", target_port); + state.channel = grpc_insecure_channel_create(state.target, nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("localhost"); state.call = grpc_channel_create_call( state.channel, nullptr, GRPC_PROPAGATE_DEFAULTS, state.cq, @@ -231,7 +230,7 @@ static void cleanup_rpc() { } while (ev.type != GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(state.cq); grpc_channel_destroy(state.channel); - state.target.reset(); + gpr_free(state.target); } typedef struct { diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 3bb6d2e23b6..446e7b045a1 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -24,7 +24,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" @@ -77,10 +77,10 @@ static void run_test(bool wait_for_ready, bool use_service_config) { /* create a call, channel to a port which will refuse connection */ int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr addr; - grpc_core::JoinHostPort(&addr, "127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr.get()); - chan = grpc_insecure_channel_create(addr.get(), args, nullptr); + char* addr; + gpr_join_host_port(&addr, "127.0.0.1", port); + gpr_log(GPR_INFO, "server: %s", addr); + chan = grpc_insecure_channel_create(addr, args, nullptr); grpc_slice host = grpc_slice_from_static_string("nonexistant"); gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); call = @@ -88,6 +88,8 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_slice_from_static_string("/service/method"), &host, deadline, nullptr); + gpr_free(addr); + memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index cb49e0030b4..330af8fce07 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -28,8 +28,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -70,6 +70,8 @@ static void log_resolved_addrs(const char* label, const char* hostname) { void test_connect(const char* server_host, const char* client_host, int port, int expect_ok) { + char* client_hostport; + char* server_hostport; grpc_channel* client; grpc_server* server; grpc_completion_queue* cq; @@ -97,8 +99,7 @@ void test_connect(const char* server_host, const char* client_host, int port, picked_port = 1; } - grpc_core::UniquePtr server_hostport; - grpc_core::JoinHostPort(&server_hostport, server_host, port); + gpr_join_host_port(&server_hostport, server_host, port); grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); @@ -110,7 +111,7 @@ void test_connect(const char* server_host, const char* client_host, int port, server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(server, cq, nullptr); GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port( - server, server_hostport.get())) > 0); + server, server_hostport)) > 0); if (port == 0) { port = got_port; } else { @@ -120,7 +121,6 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv = cq_verifier_create(cq); /* Create client. */ - grpc_core::UniquePtr client_hostport; if (client_host[0] == 'i') { /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */ size_t i; @@ -139,8 +139,8 @@ void test_connect(const char* server_host, const char* client_host, int port, gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port); gpr_free(uri_part_str); } - client_hostport.reset(gpr_strjoin_sep((const char**)hosts_with_port, - uri_parts.count, ",", nullptr)); + client_hostport = gpr_strjoin_sep((const char**)hosts_with_port, + uri_parts.count, ",", nullptr); for (i = 0; i < uri_parts.count; i++) { gpr_free(hosts_with_port[i]); } @@ -148,17 +148,18 @@ void test_connect(const char* server_host, const char* client_host, int port, grpc_slice_buffer_destroy(&uri_parts); grpc_slice_unref(uri_slice); } else { - grpc_core::JoinHostPort(&client_hostport, client_host, port); + gpr_join_host_port(&client_hostport, client_host, port); } - client = - grpc_insecure_channel_create(client_hostport.get(), nullptr, nullptr); + client = grpc_insecure_channel_create(client_hostport, nullptr, nullptr); gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport.get(), client_hostport.get(), - expect_ok ? "success" : "failure"); + server_hostport, client_hostport, expect_ok ? "success" : "failure"); log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); + gpr_free(client_hostport); + gpr_free(server_hostport); + if (expect_ok) { /* Normal deadline, shouldn't be reached. */ deadline = grpc_timeout_milliseconds_to_deadline(60000); diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 72cb96138e1..60442ddcc77 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -29,23 +29,25 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_fixture_data { + char* localaddr; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -69,7 +71,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, grpc_arg arg = make_census_enable_arg(); client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); f->client = - grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client); { grpc_core::ExecCtx exec_ctx; @@ -92,15 +94,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_channel_args_destroy(server_args); } grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index dd0c1fe0201..01e5ae1b7b5 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -30,29 +30,28 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/compression/compression_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_compression_fixture_data { - ~fullstack_compression_fixture_data() { - grpc_channel_args_destroy(client_args_compression); - grpc_channel_args_destroy(server_args_compression); - } - grpc_core::UniquePtr localaddr; - grpc_channel_args* client_args_compression = nullptr; - grpc_channel_args* server_args_compression = nullptr; -}; +typedef struct fullstack_compression_fixture_data { + char* localaddr; + grpc_channel_args* client_args_compression; + grpc_channel_args* server_args_compression; +} fullstack_compression_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_compression_fixture_data* ffd = - grpc_core::New(); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + static_cast( + gpr_malloc(sizeof(fullstack_compression_fixture_data))); + memset(ffd, 0, sizeof(fullstack_compression_fixture_data)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; @@ -74,7 +73,7 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f, grpc_channel_args_set_channel_default_compression_algorithm( client_args, GRPC_COMPRESS_GZIP); f->client = grpc_insecure_channel_create( - ffd->localaddr.get(), ffd->client_args_compression, nullptr); + ffd->localaddr, ffd->client_args_compression, nullptr); } void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, @@ -93,8 +92,7 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(ffd->server_args_compression, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } @@ -102,7 +100,10 @@ void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; fullstack_compression_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + grpc_channel_args_destroy(ffd->client_args_compression); + grpc_channel_args_destroy(ffd->server_args_compression); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index 1375549ed6c..ad83aab39f4 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -25,24 +25,26 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_secure_fixture_data { + char* localaddr; +} fullstack_secure_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); + memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -64,8 +66,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -80,7 +82,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -89,7 +91,8 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static void chttp2_init_client_fake_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index ac4913674f0..6d559c4e516 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -33,25 +33,26 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_fixture_data { + char* localaddr; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -65,7 +66,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client); } @@ -78,15 +79,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index 04de2a20182..b8dbe261183 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -34,24 +34,25 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_fixture_data { + char* localaddr; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -65,7 +66,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client); } @@ -78,15 +79,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index 8cfba4587e0..cb0f7d275b3 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -30,7 +30,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -39,20 +39,24 @@ static char* workarounds_arg[GRPC_MAX_WORKAROUND_ID] = { const_cast(GRPC_ARG_WORKAROUND_CRONET_COMPRESSION)}; -struct fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_fixture_data { + char* localaddr; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + return f; } @@ -61,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client); } @@ -84,8 +88,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args_new, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); grpc_channel_args_destroy(server_args_new); } @@ -93,7 +96,8 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index a3f2f25db5f..c0d21288c7e 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -28,24 +28,25 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_fixture_data { + char* localaddr; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -59,7 +60,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client); } @@ -72,15 +73,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 18ba0e7f847..9b6a81494e1 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -30,26 +30,26 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_fixture_data { - ~fullstack_fixture_data() { grpc_end2end_http_proxy_destroy(proxy); } - grpc_core::UniquePtr server_addr; - grpc_end2end_http_proxy* proxy = nullptr; -}; +typedef struct fullstack_fixture_data { + char* server_addr; + grpc_end2end_http_proxy* proxy; +} fullstack_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; memset(&f, 0, sizeof(f)); - fullstack_fixture_data* ffd = grpc_core::New(); + fullstack_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(fullstack_fixture_data))); const int server_port = grpc_pick_unused_port_or_die(); - grpc_core::JoinHostPort(&ffd->server_addr, "localhost", server_port); + gpr_join_host_port(&ffd->server_addr, "localhost", server_port); /* Passing client_args to proxy_create for the case of checking for proxy auth */ @@ -81,8 +81,8 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, } gpr_setenv("http_proxy", proxy_uri); gpr_free(proxy_uri); - f->client = grpc_insecure_channel_create(ffd->server_addr.get(), client_args, - nullptr); + f->client = + grpc_insecure_channel_create(ffd->server_addr, client_args, nullptr); GPR_ASSERT(f->client); } @@ -95,15 +95,16 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT( - grpc_server_add_insecure_http2_port(f->server, ffd->server_addr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr)); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->server_addr); + grpc_end2end_http_proxy_destroy(ffd->proxy); + gpr_free(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc index e27844be2df..f6996bf6be3 100644 --- a/test/core/end2end/fixtures/h2_local_ipv4.cc +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - grpc_core::JoinHostPort( + gpr_join_host_port( &static_cast(f.fixture_data) ->localaddr, "127.0.0.1", port); diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc index 91acaa347f6..e360727ca82 100644 --- a/test/core/end2end/fixtures/h2_local_ipv6.cc +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - grpc_core::JoinHostPort( + gpr_join_host_port( &static_cast(f.fixture_data) ->localaddr, "[::1]", port); diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc index 6c748896760..f1bce213dc2 100644 --- a/test/core/end2end/fixtures/h2_local_uds.cc +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -30,10 +30,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); - char* out = nullptr; - gpr_asprintf(&out, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); - static_cast(f.fixture_data) - ->localaddr.reset(out); + gpr_asprintf( + &static_cast(f.fixture_data) + ->localaddr, + "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); return f; } diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 513fded4b62..113a6b11732 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -25,7 +25,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -36,9 +36,9 @@ static const char oauth2_md[] = "Bearer aaslkfjs424535asdf"; static const char* client_identity_property_name = "smurf_name"; static const char* client_identity = "Brainy Smurf"; -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_secure_fixture_data { + char* localaddr; +} fullstack_secure_fixture_data; static const grpc_metadata* find_metadata(const grpc_metadata* md, size_t md_count, const char* key, @@ -95,12 +95,16 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + return f; } @@ -109,8 +113,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -125,7 +129,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -134,7 +138,8 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index f0ada89d14d..e334396ea7c 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -28,6 +28,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/proxy.h" diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index 4352ef640cd..cdf091bac10 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -28,9 +28,9 @@ #include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/security/credentials/credentials.h" @@ -42,15 +42,10 @@ typedef grpc_core::InlinedVector ThreadList; -struct fullstack_secure_fixture_data { - ~fullstack_secure_fixture_data() { - for (size_t ind = 0; ind < thd_list.size(); ind++) { - thd_list[ind].Join(); - } - } - grpc_core::UniquePtr localaddr; +typedef struct fullstack_secure_fixture_data { + char* localaddr; ThreadList thd_list; -}; +} fullstack_secure_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { @@ -59,7 +54,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( fullstack_secure_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); @@ -79,8 +74,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -95,7 +90,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -104,6 +99,10 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); + for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { + ffd->thd_list[ind].Join(); + } + gpr_free(ffd->localaddr); grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index cb55bb72061..3fc9bc7f329 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,28 +25,29 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_secure_fixture_data { + char* localaddr; +} fullstack_secure_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -68,8 +69,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -84,7 +85,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -93,7 +94,8 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 2a9591845b9..1d54a431364 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,19 +25,19 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; - bool server_credential_reloaded = false; -}; +typedef struct fullstack_secure_fixture_data { + char* localaddr; + bool server_credential_reloaded; +} fullstack_secure_fixture_data; static grpc_ssl_certificate_config_reload_status ssl_server_certificate_config_callback( @@ -64,9 +64,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -88,8 +89,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -105,7 +106,7 @@ static void chttp2_init_server_secure_fullstack( ffd->server_credential_reloaded = false; f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -114,7 +115,8 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index b16ffa1b8b8..d5f695b1575 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,6 +25,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index 2b6c73d39c7..f251bbd28c5 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -31,6 +31,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index da2381aa0a0..6b5513f160e 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -31,8 +31,8 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/closure.h" @@ -53,7 +53,8 @@ struct grpc_end2end_http_proxy { grpc_end2end_http_proxy() - : server(nullptr), + : proxy_name(nullptr), + server(nullptr), channel_args(nullptr), mu(nullptr), pollset(nullptr), @@ -61,7 +62,7 @@ struct grpc_end2end_http_proxy { gpr_ref_init(&users, 1); combiner = grpc_combiner_create(); } - grpc_core::UniquePtr proxy_name; + char* proxy_name; grpc_core::Thread thd; grpc_tcp_server* server; grpc_channel_args* channel_args; @@ -531,8 +532,8 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_end2end_http_proxy* proxy = grpc_core::New(); // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); - grpc_core::JoinHostPort(&proxy->proxy_name, "localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.get()); + gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); + gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name); // Create TCP server. proxy->channel_args = grpc_channel_args_copy(args); grpc_error* error = @@ -572,6 +573,7 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { proxy->thd.Join(); grpc_tcp_server_shutdown_listeners(proxy->server); grpc_tcp_server_unref(proxy->server); + gpr_free(proxy->proxy_name); grpc_channel_args_destroy(proxy->channel_args); grpc_pollset_shutdown(proxy->pollset, GRPC_CLOSURE_CREATE(destroy_pollset, proxy->pollset, @@ -582,5 +584,5 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { const char* grpc_end2end_http_proxy_get_proxy_name( grpc_end2end_http_proxy* proxy) { - return proxy->proxy_name.get(); + return proxy->proxy_name; } diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index 70cc6b05479..dadf3ef455d 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -28,6 +28,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/inproc/inproc_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/local_util.cc b/test/core/end2end/fixtures/local_util.cc index 767f3a28ef8..5f0b0300ac0 100644 --- a/test/core/end2end/fixtures/local_util.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -27,6 +27,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/server.h" @@ -36,7 +37,8 @@ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; grpc_end2end_local_fullstack_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -50,8 +52,8 @@ void grpc_end2end_local_chttp2_init_client_fullstack( grpc_channel_credentials* creds = grpc_local_credentials_create(type); grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -97,8 +99,8 @@ void grpc_end2end_local_chttp2_init_server_fullstack( nullptr}; grpc_server_credentials_set_auth_metadata_processor(creds, processor); } - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), - creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds)); grpc_server_credentials_release(creds); grpc_server_start(f->server); } @@ -107,5 +109,6 @@ void grpc_end2end_local_chttp2_tear_down_fullstack( grpc_end2end_test_fixture* f) { grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h index df204d2fab2..f133b4d977e 100644 --- a/test/core/end2end/fixtures/local_util.h +++ b/test/core/end2end/fixtures/local_util.h @@ -22,9 +22,9 @@ #include "src/core/lib/surface/channel.h" -struct grpc_end2end_local_fullstack_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct grpc_end2end_local_fullstack_fixture_data { + char* localaddr; +} grpc_end2end_local_fullstack_fixture_data; /* Utility functions shared by h2_local tests. */ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index 4ae7450b0df..869b6e846d3 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,15 +24,16 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "test/core/util/port.h" struct grpc_end2end_proxy { grpc_end2end_proxy() - : cq(nullptr), + : proxy_port(nullptr), + server_port(nullptr), + cq(nullptr), server(nullptr), client(nullptr), shutdown(false), @@ -41,8 +42,8 @@ struct grpc_end2end_proxy { memset(&new_call_metadata, 0, sizeof(new_call_metadata)); } grpc_core::Thread thd; - grpc_core::UniquePtr proxy_port; - grpc_core::UniquePtr server_port; + char* proxy_port; + char* server_port; grpc_completion_queue* cq; grpc_server* server; grpc_channel* client; @@ -91,15 +92,15 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_end2end_proxy* proxy = grpc_core::New(); - grpc_core::JoinHostPort(&proxy->proxy_port, "localhost", proxy_port); - grpc_core::JoinHostPort(&proxy->server_port, "localhost", server_port); + gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); + gpr_join_host_port(&proxy->server_port, "localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.get(), - proxy->server_port.get()); + gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port, + proxy->server_port); proxy->cq = grpc_completion_queue_create_for_next(nullptr); - proxy->server = def->create_server(proxy->proxy_port.get(), server_args); - proxy->client = def->create_client(proxy->server_port.get(), client_args); + proxy->server = def->create_server(proxy->proxy_port, server_args); + proxy->client = def->create_client(proxy->server_port, client_args); grpc_server_register_completion_queue(proxy->server, proxy->cq, nullptr); grpc_server_start(proxy->server); @@ -130,6 +131,8 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_server_shutdown_and_notify(proxy->server, proxy->cq, new_closure(shutdown_complete, proxy)); proxy->thd.Join(); + gpr_free(proxy->proxy_port); + gpr_free(proxy->server_port); grpc_server_destroy(proxy->server); grpc_channel_destroy(proxy->client); grpc_completion_queue_destroy(proxy->cq); @@ -438,9 +441,9 @@ static void thread_main(void* arg) { } const char* grpc_end2end_proxy_get_client_target(grpc_end2end_proxy* proxy) { - return proxy->proxy_port.get(); + return proxy->proxy_port; } const char* grpc_end2end_proxy_get_server_port(grpc_end2end_proxy* proxy) { - return proxy->server_port.get(); + return proxy->server_port; } diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index 34a9ef760b5..e9285778a2d 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -40,19 +40,20 @@ namespace grpc { namespace testing { -struct fullstack_secure_fixture_data { - grpc_core::UniquePtr localaddr; -}; +typedef struct fullstack_secure_fixture_data { + char* localaddr; +} fullstack_secure_fixture_data; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - grpc_core::New(); + static_cast( + gpr_malloc(sizeof(fullstack_secure_fixture_data))); memset(&f, 0, sizeof(f)); - grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); + gpr_join_host_port(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -72,8 +73,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), - client_args, nullptr); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -88,7 +89,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -97,7 +98,8 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - grpc_core::Delete(ffd); + gpr_free(ffd->localaddr); + gpr_free(ffd); } static int fail_server_auth_check(grpc_channel_args* server_args) { diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index 6ffc138820e..b2d0a5e1133 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -215,18 +215,19 @@ void drain_cq(grpc_completion_queue* cq) { TEST(H2SessionReuseTest, SingleReuse) { int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr server_addr; - grpc_core::JoinHostPort(&server_addr, "localhost", port); + char* server_addr; + gpr_join_host_port(&server_addr, "localhost", port); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_ssl_session_cache* cache = grpc_ssl_session_cache_create_lru(16); - grpc_server* server = server_create(cq, server_addr.get()); + grpc_server* server = server_create(cq, server_addr); - do_round_trip(cq, server, server_addr.get(), cache, false); - do_round_trip(cq, server, server_addr.get(), cache, true); - do_round_trip(cq, server, server_addr.get(), cache, true); + do_round_trip(cq, server, server_addr, cache, false); + do_round_trip(cq, server, server_addr, cache, true); + do_round_trip(cq, server, server_addr, cache, true); + gpr_free(server_addr); grpc_ssl_session_cache_destroy(cache); GPR_ASSERT(grpc_completion_queue_next( diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index 5f920fad638..bd28d192984 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -25,8 +25,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -55,6 +54,7 @@ static struct test_state g_state; static void prepare_test(int is_client) { int port = grpc_pick_unused_port_or_die(); + char* server_hostport; grpc_op* op; g_state.is_client = is_client; grpc_metadata_array_init(&g_state.initial_metadata_recv); @@ -77,13 +77,14 @@ static void prepare_test(int is_client) { } else { g_state.server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(g_state.server, g_state.cq, nullptr); - grpc_core::UniquePtr server_hostport; - grpc_core::JoinHostPort(&server_hostport, "0.0.0.0", port); - grpc_server_add_insecure_http2_port(g_state.server, server_hostport.get()); + gpr_join_host_port(&server_hostport, "0.0.0.0", port); + grpc_server_add_insecure_http2_port(g_state.server, server_hostport); grpc_server_start(g_state.server); - grpc_core::JoinHostPort(&server_hostport, "localhost", port); + gpr_free(server_hostport); + gpr_join_host_port(&server_hostport, "localhost", port); g_state.chan = - grpc_insecure_channel_create(server_hostport.get(), nullptr, nullptr); + grpc_insecure_channel_create(server_hostport, nullptr, nullptr); + gpr_free(server_hostport); grpc_slice host = grpc_slice_from_static_string("bar"); g_state.call = grpc_channel_create_call( g_state.chan, nullptr, GRPC_PROPAGATE_DEFAULTS, g_state.cq, diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc index 474b4fbbc3b..32bc9896414 100644 --- a/test/core/fling/fling_stream_test.cc +++ b/test/core/fling/fling_stream_test.cc @@ -22,8 +22,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,24 +46,23 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - grpc_core::UniquePtr joined; - grpc_core::JoinHostPort(&joined, "::", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "::", port); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - grpc_core::JoinHostPort(&joined, "127.0.0.1", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "127.0.0.1", port); args[3] = const_cast("--scenario=ping-pong-stream"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc index 3667d48f010..3587a4acaae 100644 --- a/test/core/fling/fling_test.cc +++ b/test/core/fling/fling_test.cc @@ -22,9 +22,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -47,24 +46,23 @@ int main(int argc, const char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - grpc_core::UniquePtr joined; - grpc_core::JoinHostPort(&joined, "::", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "::", port); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - grpc_core::JoinHostPort(&joined, "127.0.0.1", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "127.0.0.1", port); args[3] = const_cast("--scenario=ping-pong-request"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/server.cc b/test/core/fling/server.cc index 241ac71bc7d..cf7e2465d9e 100644 --- a/test/core/fling/server.cc +++ b/test/core/fling/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" @@ -172,7 +172,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_event ev; call_state* s; - grpc_core::UniquePtr addr_buf; + char* addr_buf = nullptr; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -199,8 +199,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf.get(); + gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf; } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -220,8 +220,8 @@ int main(int argc, char** argv) { grpc_server_register_completion_queue(server, cq, nullptr); grpc_server_start(server); - addr = nullptr; - addr_buf.reset(); + gpr_free(addr_buf); + addr = addr_buf = nullptr; grpc_call_details_init(&call_details); diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index c2b2576ff03..434d55e0451 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -58,6 +58,16 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "host_port_test", + srcs = ["host_port_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "log_test", srcs = ["log_test.cc"], diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gpr/host_port_test.cc similarity index 86% rename from test/core/gprpp/host_port_test.cc rename to test/core/gpr/host_port_test.cc index 3474e6dc494..b01bbf4b695 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gpr/host_port_test.cc @@ -21,17 +21,18 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "test/core/util/test_config.h" static void join_host_port_expect(const char* host, int port, const char* expected) { - grpc_core::UniquePtr buf; + char* buf; int len; - len = grpc_core::JoinHostPort(&buf, host, port); + len = gpr_join_host_port(&buf, host, port); GPR_ASSERT(len >= 0); - GPR_ASSERT(strlen(expected) == static_cast(len)); - GPR_ASSERT(strcmp(expected, buf.get()) == 0); + GPR_ASSERT(strlen(expected) == (size_t)len); + GPR_ASSERT(strcmp(expected, buf) == 0); + gpr_free(buf); } static void test_join_host_port(void) { diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index 5cee96a3ad2..cd3232addfd 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -64,16 +64,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "host_port_test", - srcs = ["host_port_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "grpc_core_map_test", srcs = ["map_test.cc"], @@ -166,19 +156,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "string_view_test", - srcs = ["string_view_test.cc"], - external_deps = [ - "gtest", - ], - language = "C++", - deps = [ - "//:gpr_base", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "thd_test", srcs = ["thd_test.cc"], diff --git a/test/core/gprpp/string_view_test.cc b/test/core/gprpp/string_view_test.cc deleted file mode 100644 index 1c8adb1db14..00000000000 --- a/test/core/gprpp/string_view_test.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/gprpp/string_view.h" - -#include -#include "src/core/lib/gprpp/memory.h" -#include "test/core/util/test_config.h" - -namespace grpc_core { -namespace testing { - -TEST(StringViewTest, Empty) { - grpc_core::StringView empty; - EXPECT_TRUE(empty.empty()); - EXPECT_EQ(empty.size(), 0lu); - - grpc_core::StringView empty_buf(""); - EXPECT_TRUE(empty_buf.empty()); - EXPECT_EQ(empty_buf.size(), 0lu); - - grpc_core::StringView empty_trimmed("foo", 0); - EXPECT_TRUE(empty_trimmed.empty()); - EXPECT_EQ(empty_trimmed.size(), 0lu); - - grpc_core::StringView empty_slice(grpc_empty_slice()); - EXPECT_TRUE(empty_slice.empty()); - EXPECT_EQ(empty_slice.size(), 0lu); -} - -TEST(StringViewTest, Size) { - constexpr char kStr[] = "foo"; - grpc_core::StringView str1(kStr); - EXPECT_EQ(str1.size(), strlen(kStr)); - grpc_core::StringView str2(kStr, 2); - EXPECT_EQ(str2.size(), 2lu); -} - -TEST(StringViewTest, Data) { - constexpr char kStr[] = "foo-bar"; - grpc_core::StringView str(kStr); - EXPECT_EQ(str.size(), strlen(kStr)); - for (size_t i = 0; i < strlen(kStr); ++i) { - EXPECT_EQ(str[i], kStr[i]); - } -} - -TEST(StringViewTest, Slice) { - constexpr char kStr[] = "foo"; - grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); - EXPECT_EQ(slice.size(), strlen(kStr)); -} - -TEST(StringViewTest, Dup) { - constexpr char kStr[] = "foo"; - grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); - grpc_core::UniquePtr dup = slice.dup(); - EXPECT_EQ(0, strcmp(kStr, dup.get())); - EXPECT_EQ(slice.size(), strlen(kStr)); -} - -TEST(StringViewTest, Eq) { - constexpr char kStr1[] = "foo"; - constexpr char kStr2[] = "bar"; - grpc_core::StringView str1(kStr1); - EXPECT_EQ(kStr1, str1); - EXPECT_EQ(str1, kStr1); - grpc_core::StringView slice1(grpc_slice_from_static_string(kStr1)); - EXPECT_EQ(slice1, str1); - EXPECT_EQ(str1, slice1); - EXPECT_NE(slice1, kStr2); - EXPECT_NE(kStr2, slice1); - grpc_core::StringView slice2(grpc_slice_from_static_string(kStr2)); - EXPECT_NE(slice2, str1); - EXPECT_NE(str1, slice2); -} - -TEST(StringViewTest, Cmp) { - constexpr char kStr1[] = "abc"; - constexpr char kStr2[] = "abd"; - constexpr char kStr3[] = "abcd"; - grpc_core::StringView str1(kStr1); - grpc_core::StringView str2(kStr2); - grpc_core::StringView str3(kStr3); - EXPECT_EQ(str1.cmp(str1), 0); - EXPECT_LT(str1.cmp(str2), 0); - EXPECT_LT(str1.cmp(str3), 0); - EXPECT_EQ(str2.cmp(str2), 0); - EXPECT_GT(str2.cmp(str1), 0); - EXPECT_GT(str2.cmp(str3), 0); - EXPECT_EQ(str3.cmp(str3), 0); - EXPECT_GT(str3.cmp(str1), 0); - EXPECT_LT(str3.cmp(str2), 0); -} - -TEST(StringViewTest, RemovePrefix) { - constexpr char kStr[] = "abcd"; - grpc_core::StringView str(kStr); - str.remove_prefix(1); - EXPECT_EQ("bcd", str); - str.remove_prefix(2); - EXPECT_EQ("d", str); - str.remove_prefix(1); - EXPECT_EQ("", str); -} - -TEST(StringViewTest, RemoveSuffix) { - constexpr char kStr[] = "abcd"; - grpc_core::StringView str(kStr); - str.remove_suffix(1); - EXPECT_EQ("abc", str); - str.remove_suffix(2); - EXPECT_EQ("a", str); - str.remove_suffix(1); - EXPECT_EQ("", str); -} - -TEST(StringViewTest, Substring) { - constexpr char kStr[] = "abcd"; - grpc_core::StringView str(kStr); - EXPECT_EQ("bcd", str.substr(1)); - EXPECT_EQ("bc", str.substr(1, 2)); -} - -TEST(StringViewTest, Find) { - // Passing StringView::npos directly to GTEST macros result in link errors. - // Store the value in a local variable and use it in the test. - const size_t npos = grpc_core::StringView::npos; - constexpr char kStr[] = "abacad"; - grpc_core::StringView str(kStr); - EXPECT_EQ(0ul, str.find('a')); - EXPECT_EQ(2ul, str.find('a', 1)); - EXPECT_EQ(4ul, str.find('a', 3)); - EXPECT_EQ(1ul, str.find('b')); - EXPECT_EQ(npos, str.find('b', 2)); - EXPECT_EQ(npos, str.find('z')); -} - -} // namespace testing -} // namespace grpc_core - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc index 5df8af5658b..5c35b4e1d36 100644 --- a/test/core/memory_usage/memory_usage_test.cc +++ b/test/core/memory_usage/memory_usage_test.cc @@ -22,8 +22,8 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +46,22 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/memory_usage_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - grpc_core::UniquePtr joined; - grpc_core::JoinHostPort(&joined, "::", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "::", port); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/memory_usage_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - grpc_core::JoinHostPort(&joined, "127.0.0.1", port); - args[2] = joined.get(); + gpr_join_host_port(&args[2], "127.0.0.1", port); args[3] = const_cast("--warmup=1000"); args[4] = const_cast("--benchmark=9000"); cli = gpr_subprocess_create(5, (const char**)args); gpr_free(args[0]); + gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index ecdf17925ec..6fb14fa31a0 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -149,7 +149,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_memory_counters_init(); grpc_event ev; - grpc_core::UniquePtr addr_buf; + char* addr_buf = nullptr; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -174,8 +174,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf.get(); + gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf; } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -202,8 +202,8 @@ int main(int argc, char** argv) { struct grpc_memory_counters after_server_create = grpc_memory_counters_snapshot(); - addr = nullptr; - addr_buf.reset(); + gpr_free(addr_buf); + addr = addr_buf = nullptr; // initialize call instances for (int i = 0; i < static_cast(sizeof(calls) / sizeof(fling_call)); diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 2c9b0d9aaed..454cbd5747e 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -22,8 +22,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -67,11 +66,13 @@ static void channel_idle_poll_for_timeout(grpc_channel* channel, static void run_timeouts_test(const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - grpc_core::UniquePtr addr; + char* addr; + grpc_init(); - grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - grpc_channel* channel = fixture->create_channel(addr.get()); + gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); + + grpc_channel* channel = fixture->create_channel(addr); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then let it time out */ @@ -110,6 +111,7 @@ static void run_timeouts_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); + gpr_free(addr); } /* An edge scenario; sets channel state to explicitly, and outside @@ -118,11 +120,13 @@ static void run_channel_shutdown_before_timeout_test( const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - grpc_core::UniquePtr addr; + char* addr; + grpc_init(); - grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - grpc_channel* channel = fixture->create_channel(addr.get()); + gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); + + grpc_channel* channel = fixture->create_channel(addr); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then shut down the channel before the timer goes off */ @@ -150,6 +154,7 @@ static void run_channel_shutdown_before_timeout_test( grpc_completion_queue_destroy(cq); grpc_shutdown(); + gpr_free(addr); } static grpc_channel* insecure_test_create_channel(const char* addr) { diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 46c4a24f5ed..3f9a7baf98b 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -22,7 +22,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -56,11 +56,11 @@ static void run_test(const test_fixture* fixture) { grpc_init(); - grpc_core::UniquePtr addr; - grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); + char* addr; + gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); grpc_server* server = grpc_server_create(nullptr, nullptr); - fixture->add_server_port(server, addr.get()); + fixture->add_server_port(server, addr); grpc_completion_queue* server_cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, server_cq, nullptr); @@ -73,7 +73,7 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_channel* channels[NUM_CONNECTIONS]; for (size_t i = 0; i < NUM_CONNECTIONS; i++) { - channels[i] = fixture->create_channel(addr.get()); + channels[i] = fixture->create_channel(addr); gpr_timespec connect_deadline = grpc_timeout_seconds_to_deadline(30); grpc_connectivity_state state; @@ -116,6 +116,7 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); + gpr_free(addr); } static void insecure_test_add_port(grpc_server* server, const char* addr) { diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index a88362e13b0..ffb7f14f987 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/tsi/fake_transport_security.h" @@ -47,17 +47,17 @@ void test_add_same_port_twice() { grpc_channel_args args = {1, &a}; int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr addr; + char* addr = nullptr; grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server* server = grpc_server_create(&args, nullptr); grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - grpc_core::JoinHostPort(&addr, "localhost", port); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); - GPR_ASSERT( - grpc_server_add_secure_http2_port(server, addr.get(), fake_creds) == 0); + gpr_join_host_port(&addr, "localhost", port); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds) == 0); grpc_server_credentials_release(fake_creds); + gpr_free(addr); grpc_server_shutdown_and_notify(server, cq, nullptr); grpc_completion_queue_pluck(cq, nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index 185a6757743..2fc166546b0 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/port.h" @@ -106,19 +106,18 @@ void test_bind_server_twice(void) { void test_bind_server_to_addr(const char* host, bool secure) { int port = grpc_pick_unused_port_or_die(); - grpc_core::UniquePtr addr; - grpc_core::JoinHostPort(&addr, host, port); - gpr_log(GPR_INFO, "Test bind to %s", addr.get()); + char* addr; + gpr_join_host_port(&addr, host, port); + gpr_log(GPR_INFO, "Test bind to %s", addr); grpc_server* server = grpc_server_create(nullptr, nullptr); if (secure) { grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - GPR_ASSERT( - grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); grpc_server_credentials_release(fake_creds); } else { - GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr.get())); + GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr)); } grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, cq, nullptr); @@ -127,6 +126,7 @@ void test_bind_server_to_addr(const char* host, bool secure) { grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), nullptr); grpc_server_destroy(server); grpc_completion_queue_destroy(cq); + gpr_free(addr); } static int external_dns_works(const char* host) { diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index 03c088db772..144ad64f095 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -25,6 +25,7 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index d7803e53555..170584df2b9 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index e0bacb3cfd6..8e45b877212 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -32,6 +32,7 @@ #include "test/core/util/port.h" #include "test/cpp/util/test_config.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_utils_posix.h" diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index a3d9936606d..affc75bc634 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -40,8 +40,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -64,28 +64,30 @@ struct TestAddress { }; grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) { - grpc_core::UniquePtr host; - grpc_core::UniquePtr port; + char* host; + char* port; grpc_resolved_address resolved_addr; - grpc_core::SplitHostPort(test_addr.dest_addr.c_str(), &host, &port); + gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port); if (test_addr.family == AF_INET) { sockaddr_in in_dest; memset(&in_dest, 0, sizeof(sockaddr_in)); - in_dest.sin_port = htons(atoi(port.get())); + in_dest.sin_port = htons(atoi(port)); in_dest.sin_family = AF_INET; - GPR_ASSERT(inet_pton(AF_INET, host.get(), &in_dest.sin_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1); memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in)); resolved_addr.len = sizeof(sockaddr_in); } else { GPR_ASSERT(test_addr.family == AF_INET6); sockaddr_in6 in6_dest; memset(&in6_dest, 0, sizeof(sockaddr_in6)); - in6_dest.sin6_port = htons(atoi(port.get())); + in6_dest.sin6_port = htons(atoi(port)); in6_dest.sin6_family = AF_INET6; - GPR_ASSERT(inet_pton(AF_INET6, host.get(), &in6_dest.sin6_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1); memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6)); resolved_addr.len = sizeof(sockaddr_in6); } + gpr_free(host); + gpr_free(port); return resolved_addr; } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 2d1a13d25a6..667011ae291 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -33,6 +33,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/thd.h" diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 67ed307d2d7..6cea8143907 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,8 +46,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" @@ -506,10 +506,10 @@ int g_fake_non_responsive_dns_server_port = -1; void InjectBrokenNameServerList(ares_channel channel) { struct ares_addr_port_node dns_server_addrs[2]; memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); - grpc_core::UniquePtr unused_host; - grpc_core::UniquePtr local_dns_server_port; - GPR_ASSERT(grpc_core::SplitHostPort(FLAGS_local_dns_server_address.c_str(), - &unused_host, &local_dns_server_port)); + char* unused_host; + char* local_dns_server_port; + GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); gpr_log(GPR_DEBUG, "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " "Good server address:%s", @@ -528,10 +528,12 @@ void InjectBrokenNameServerList(ares_channel channel) { dns_server_addrs[1].family = AF_INET; ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; - dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.get()); - dns_server_addrs[1].udp_port = atoi(local_dns_server_port.get()); + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port); dns_server_addrs[1].next = nullptr; GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); + gpr_free(local_dns_server_port); + gpr_free(unused_host); } void StartResolvingLocked(void* arg, grpc_error* unused) { diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 5fc14ddbabd..668d9abf5ca 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -33,6 +33,7 @@ #include #include +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index cfc3c8e9a06..7d4d5d99446 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -31,7 +31,7 @@ #include #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/port.h" @@ -52,10 +52,15 @@ using std::vector; namespace grpc { namespace testing { static std::string get_host(const std::string& worker) { - grpc_core::StringView host; - grpc_core::StringView port; - grpc_core::SplitHostPort(worker.c_str(), &host, &port); - return std::string(host.data(), host.size()); + char* host; + char* port; + + gpr_split_host_port(worker.c_str(), &host, &port); + const string s(host); + + gpr_free(host); + gpr_free(port); + return s; } static deque get_workers(const string& env_name) { @@ -319,10 +324,11 @@ std::unique_ptr RunScenario( client_config.add_server_targets(cli_target); } else { std::string host; - grpc_core::UniquePtr cli_target; + char* cli_target; host = get_host(workers[i]); - grpc_core::JoinHostPort(&cli_target, host.c_str(), init_status.port()); - client_config.add_server_targets(cli_target.get()); + gpr_join_host_port(&cli_target, host.c_str(), init_status.port()); + client_config.add_server_targets(cli_target); + gpr_free(cli_target); } } diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index bdf94d86c10..23fe72316a1 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" @@ -279,11 +279,12 @@ QpsWorker::QpsWorker(int driver_port, int server_port, std::unique_ptr builder = CreateQpsServerBuilder(); if (driver_port >= 0) { - grpc_core::UniquePtr server_address; - grpc_core::JoinHostPort(&server_address, "::", driver_port); + char* server_address = nullptr; + gpr_join_host_port(&server_address, "::", driver_port); builder->AddListeningPort( - server_address.get(), + server_address, GetCredentialsProvider()->GetServerCredentials(credential_type)); + gpr_free(server_address); } builder->RegisterService(impl_.get()); diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index e9978212f95..a5f8347c269 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/completion_queue.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" @@ -80,10 +80,11 @@ class AsyncQpsServerTest final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - grpc_core::UniquePtr server_address; - grpc_core::JoinHostPort(&server_address, "::", port_num); - builder->AddListeningPort(server_address.get(), + char* server_address = nullptr; + gpr_join_host_port(&server_address, "::", port_num); + builder->AddListeningPort(server_address, Server::CreateServerCredentials(config)); + gpr_free(server_address); } register_service(builder.get(), &async_service_); diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 1829905cb49..4a346dd0178 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -21,7 +21,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -103,10 +103,11 @@ class CallbackServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - grpc_core::UniquePtr server_address; - grpc_core::JoinHostPort(&server_address, "::", port_num); - builder->AddListeningPort(server_address.get(), + char* server_address = nullptr; + gpr_join_host_port(&server_address, "::", port_num); + builder->AddListeningPort(server_address, Server::CreateServerCredentials(config)); + gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 7b76e9c206a..2e63f5ec867 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -25,7 +25,7 @@ #include #include -#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gpr/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -160,10 +160,11 @@ class SynchronousServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - grpc_core::UniquePtr server_address; - grpc_core::JoinHostPort(&server_address, "::", port_num); - builder->AddListeningPort(server_address.get(), + char* server_address = nullptr; + gpr_join_host_port(&server_address, "::", port_num); + builder->AddListeningPort(server_address, Server::CreateServerCredentials(config)); + gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index d783dae496c..e2d753e02eb 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1076,6 +1076,7 @@ src/core/lib/debug/trace.h \ src/core/lib/gpr/alloc.h \ src/core/lib/gpr/arena.h \ src/core/lib/gpr/env.h \ +src/core/lib/gpr/host_port.h \ src/core/lib/gpr/mpscq.h \ src/core/lib/gpr/murmur_hash.h \ src/core/lib/gpr/spinlock.h \ @@ -1097,7 +1098,6 @@ src/core/lib/gprpp/global_config.h \ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ -src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1107,7 +1107,6 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ -src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/http/format_request.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1dae91d2eaf..7768bca30f5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1125,6 +1125,8 @@ src/core/lib/gpr/env.h \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ +src/core/lib/gpr/host_port.cc \ +src/core/lib/gpr/host_port.h \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -1173,8 +1175,6 @@ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ -src/core/lib/gprpp/host_port.cc \ -src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1184,7 +1184,6 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ -src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/gprpp/thd_posix.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index dc2b0531e71..8765f216dab 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -683,7 +683,7 @@ "language": "c", "name": "gpr_host_port_test", "src": [ - "test/core/gprpp/host_port_test.cc" + "test/core/gpr/host_port_test.cc" ], "third_party": false, "type": "target" @@ -5058,24 +5058,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "grpc", - "grpc++", - "grpc++_test", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "string_view_test", - "src": [ - "test/core/gprpp/string_view_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -8207,6 +8189,7 @@ "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", + "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -8233,7 +8216,6 @@ "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", - "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -8267,6 +8249,7 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", + "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8287,7 +8270,6 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8320,6 +8302,7 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", + "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8340,7 +8323,6 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8641,7 +8623,6 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", - "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", @@ -8799,7 +8780,6 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", - "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 9e835c22bb6..625d3bd295f 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5730,30 +5730,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "string_view_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, From 0e85762b67cca0e049c668a96b759217b1a1f383 Mon Sep 17 00:00:00 2001 From: Qixuan Li Date: Tue, 25 Jun 2019 11:24:17 -0700 Subject: [PATCH 491/676] add pick_first_unary --- src/proto/grpc/testing/messages.proto | 7 +++++++ test/cpp/interop/client.cc | 2 ++ test/cpp/interop/client_helper.cc | 7 +++++++ test/cpp/interop/interop_client.cc | 23 +++++++++++++++++++++++ test/cpp/interop/interop_client.h | 2 ++ 5 files changed, 41 insertions(+) diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto index 7b1b7286dce..3b966ae1b25 100644 --- a/src/proto/grpc/testing/messages.proto +++ b/src/proto/grpc/testing/messages.proto @@ -77,6 +77,9 @@ message SimpleRequest { // Whether the server should expect this request to be compressed. BoolValue expect_compressed = 8; + + // Whether SimpleResponse should include server_id. + bool fill_server_id = 9; } // Unary response, as configured by the request. @@ -88,6 +91,10 @@ message SimpleResponse { string username = 2; // OAuth scope. string oauth_scope = 3; + + // Server ID. This must be unique among different server instances, + // but the same across all RPC's made to a particular server instance. + string server_id = 4; } // Client-streaming request. diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index ccfd2bb0c45..47653b25ef9 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -222,6 +222,8 @@ int main(int argc, char** argv) { &grpc::testing::InteropClient::DoTimeoutOnSleepingServer, &client); actions["empty_stream"] = std::bind(&grpc::testing::InteropClient::DoEmptyStream, &client); + actions["pick_first_unary"] = + std::bind(&grpc::testing::InteropClient::DoPickFirstUnary, &client); if (FLAGS_use_tls) { actions["compute_engine_creds"] = std::bind(&grpc::testing::InteropClient::DoComputeEngineCreds, &client, diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index 92f07387d75..2f312542b9b 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -105,6 +105,13 @@ std::shared_ptr CreateChannelForTestCase( creds = FLAGS_custom_credentials_type == "google_default_credentials" ? nullptr : AccessTokenCredentials(GetOauth2AccessToken()); + } else if (test_case == "pick_first_unary") { + ChannelArguments channel_args; + // force using pick first policy + channel_args.SetInt(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, 0); + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, + FLAGS_server_host_override, !FLAGS_use_test_ca, + creds, channel_args); } if (FLAGS_custom_credentials_type.empty()) { transport_security security_type = diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 649abf8a938..7c9a702a726 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -948,6 +948,29 @@ bool InteropClient::DoCacheableUnary() { return true; } +bool InteropClient::DoPickFirstUnary() { + const int rpcCount = 100; + SimpleRequest request; + SimpleResponse response; + std::string first_server_id; + request.set_fill_server_id(true); + for (int i = 0; i < rpcCount; i++) { + ClientContext context; + Status s = serviceStub_.Get()->UnaryCall(&context, request, &response); + if (!AssertStatusOk(s, context.debug_error_string())) { + return false; + } + if (i == 0) { + first_server_id = response.server_id(); + gpr_log(GPR_DEBUG, "first_user_id is %s", first_server_id.c_str()); + continue; + } + GPR_ASSERT(response.server_id() == first_server_id); + } + gpr_log(GPR_DEBUG, "pick first unary successfully finished"); + return true; +} + bool InteropClient::DoCustomMetadata() { const grpc::string kEchoInitialMetadataKey("x-grpc-test-echo-initial"); const grpc::string kInitialMetadataValue("test_initial_metadata_value"); diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 22df688468b..483d9becac2 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -69,6 +69,8 @@ class InteropClient { bool DoUnimplementedMethod(); bool DoUnimplementedService(); bool DoCacheableUnary(); + // all requests are sent to one server despite multiple servers are resolved + bool DoPickFirstUnary(); // The following interop test are not yet part of the interop spec, and are // not implemented cross-language. They are considered experimental for now, From e92622eb5be9b8e53dec5a48a3c6dc7ddbf963c4 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Fri, 7 Jun 2019 15:13:47 -0700 Subject: [PATCH 492/676] Add PHP back to client_matrix.py --- tools/interop_matrix/client_matrix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 05c495f5633..7bcfa075559 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -284,9 +284,9 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.18.0', ReleaseInfo()), + # v1.19 and v1.20 were deliberately ommitted here because of an issue. + # See https://github.com/grpc/grpc/issues/18264 ('v1.21.4', ReleaseInfo()), - # TODO:https://github.com/grpc/grpc/issues/18264 - # Error in above issues needs to be resolved. ]), 'csharp': OrderedDict([ From 18fb10cdd6544ae2ec69367591a4ba2e40209b05 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 26 Jun 2019 13:59:23 -0700 Subject: [PATCH 493/676] Add some comment --- test/core/iomgr/mpmcqueue_test.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/core/iomgr/mpmcqueue_test.cc b/test/core/iomgr/mpmcqueue_test.cc index 12107e85327..a301832f608 100644 --- a/test/core/iomgr/mpmcqueue_test.cc +++ b/test/core/iomgr/mpmcqueue_test.cc @@ -33,7 +33,9 @@ struct WorkItem { WorkItem(int i) : index(i) { done = false; } }; -// Thread for put items into queue +// Thread to "produce" items and put items into queue +// It will also check that all items has been marked done and clean up all +// produced items on destructing. class ProducerThread { public: ProducerThread(grpc_core::InfLenFIFOQueue* queue, int start_index, @@ -72,6 +74,7 @@ class ProducerThread { WorkItem** items_; }; +// Thread to pull out items from queue class ConsumerThread { public: ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) { From bddcb6c906757c4741168817d27606e496074495 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 26 Jun 2019 14:28:34 -0700 Subject: [PATCH 494/676] Don't move ServerContext to impl --- BUILD | 1 - BUILD.gn | 1 - CMakeLists.txt | 3 --- Makefile | 3 --- build.yaml | 1 - gRPC-C++.podspec | 1 - include/grpcpp/server_context_impl.h | 24 ------------------- tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 1 - .../generated/sources_and_headers.json | 2 -- 10 files changed, 38 deletions(-) delete mode 100644 include/grpcpp/server_context_impl.h diff --git a/BUILD b/BUILD index 172a90e151e..87d3b978358 100644 --- a/BUILD +++ b/BUILD @@ -265,7 +265,6 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", - "include/grpcpp/server_context_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", diff --git a/BUILD.gn b/BUILD.gn index 534c88bd67f..fc9fa8dc3d0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1119,7 +1119,6 @@ config("grpc_config") { "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", - "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 46bd48cccdb..ce16506ab62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3200,7 +3200,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h - include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h @@ -3823,7 +3822,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h - include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h @@ -4824,7 +4822,6 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h - include/grpcpp/server_context_impl.h include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h diff --git a/Makefile b/Makefile index 702c571f585..e2e8aa60488 100644 --- a/Makefile +++ b/Makefile @@ -5574,7 +5574,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ - include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ @@ -6205,7 +6204,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ - include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ @@ -7155,7 +7153,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ - include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/build.yaml b/build.yaml index d63284e1267..5b9a8c1594e 100644 --- a/build.yaml +++ b/build.yaml @@ -1406,7 +1406,6 @@ filegroups: - include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h - - include/grpcpp/server_context_impl.h - include/grpcpp/server_impl.h - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 981fb345eee..6fc97c6135e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -125,7 +125,6 @@ Pod::Spec.new do |s| 'include/grpcpp/server_builder.h', 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', - 'include/grpcpp/server_context_impl.h', 'include/grpcpp/server_impl.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', diff --git a/include/grpcpp/server_context_impl.h b/include/grpcpp/server_context_impl.h deleted file mode 100644 index 3a944f3da8f..00000000000 --- a/include/grpcpp/server_context_impl.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPCPP_SERVER_CONTEXT_IMPL_H -#define GRPCPP_SERVER_CONTEXT_IMPL_H - -#include - -#endif // GRPCPP_SERVER_CONTEXT_IMPL_H diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index fe242437921..501be844410 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1020,7 +1020,6 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ -include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e500b317af8..f1dd2e54e1d 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1022,7 +1022,6 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ -include/grpcpp/server_context_impl.h \ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 98b9bdc4261..b157439a3f4 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10421,7 +10421,6 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", - "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", @@ -10550,7 +10549,6 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", - "include/grpcpp/server_context_impl.h", "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", From 7a4b6b7e302ebc970ee4225bf13e0190472b2356 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 26 Jun 2019 15:00:26 -0700 Subject: [PATCH 495/676] Update oauth2 token endpoints --- src/core/lib/security/credentials/credentials.h | 4 ++-- src/core/lib/security/credentials/jwt/json_token.h | 2 +- test/core/security/jwt_verifier_test.cc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index a9d581280d1..907cf2b02f6 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -64,8 +64,8 @@ typedef enum { #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ "/computeMetadata/v1/instance/service-accounts/default/token" -#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "www.googleapis.com" -#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/oauth2/v3/token" +#define GRPC_GOOGLE_OAUTH2_SERVICE_HOST "oauth2.googleapis.com" +#define GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH "/token" #define GRPC_SERVICE_ACCOUNT_POST_BODY_PREFIX \ "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" \ diff --git a/src/core/lib/security/credentials/jwt/json_token.h b/src/core/lib/security/credentials/jwt/json_token.h index 3ed990140d3..20390f3096a 100644 --- a/src/core/lib/security/credentials/jwt/json_token.h +++ b/src/core/lib/security/credentials/jwt/json_token.h @@ -30,7 +30,7 @@ /* --- Constants. --- */ -#define GRPC_JWT_OAUTH2_AUDIENCE "https://www.googleapis.com/oauth2/v3/token" +#define GRPC_JWT_OAUTH2_AUDIENCE "https://oauth2.googleapis.com/token" /* --- auth_json_key parsing. --- */ diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc index 70155cdd065..21a7aa47b9d 100644 --- a/test/core/security/jwt_verifier_test.cc +++ b/test/core/security/jwt_verifier_test.cc @@ -128,9 +128,9 @@ static const char good_openid_config[] = " \"issuer\": \"https://accounts.google.com\"," " \"authorization_endpoint\": " "\"https://accounts.google.com/o/oauth2/v2/auth\"," - " \"token_endpoint\": \"https://www.googleapis.com/oauth2/v4/token\"," + " \"token_endpoint\": \"https://oauth2.googleapis.com/token\"," " \"userinfo_endpoint\": \"https://www.googleapis.com/oauth2/v3/userinfo\"," - " \"revocation_endpoint\": \"https://accounts.google.com/o/oauth2/revoke\"," + " \"revocation_endpoint\": \"https://oauth2.googleapis.com/revoke\"," " \"jwks_uri\": \"https://www.googleapis.com/oauth2/v3/certs\"" "}"; From 0fc57d04142e87812884fb5f9b1b03f36b701034 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 26 Jun 2019 15:15:07 -0700 Subject: [PATCH 496/676] Slightly better codegen for hpack_encoder. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hpack_encoder::ensure_space checks to see if we need to allocate to start a frame or not. The common case is that we don't need to, so we mark that code branch as the more likely one to occur. This causes the common case to jump around less. BM_HpackEncoderEncodeDeadline 152ns ± 0% 149ns ± 0% -1.99% (p=0.000 n=19+17) BM_HpackEncoderEncodeHeader/0/16384 35.0ns ± 2% 34.6ns ± 0% -1.10% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader/1/16384 34.9ns ± 1% 34.7ns ± 1% -0.81% (p=0.007 n=20+19) BM_HpackEncoderEncodeHeader/0/16384 50.6ns ± 0% 49.1ns ± 1% -3.06% (p=0.000 n=17+19) BM_HpackEncoderEncodeHeader/0/16384 84.9ns ± 1% 82.4ns ± 1% -2.90% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader/0/16384 50.5ns ± 0% 49.2ns ± 1% -2.54% (p=0.000 n=15+19) BM_HpackEncoderEncodeHeader>/0/16384 50.8ns ± 2% 49.6ns ± 1% -2.46% (p=0.000 n=17+19) BM_HpackEncoderEncodeHeader>/0/16384 50.9ns ± 2% 49.5ns ± 1% -2.78% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 50.4ns ± 1% 49.2ns ± 1% -2.32% (p=0.000 n=18+19) BM_HpackEncoderEncodeHeader>/0/16384 50.3ns ± 0% 49.2ns ± 1% -2.16% (p=0.000 n=18+19) BM_HpackEncoderEncodeHeader>/0/16384 50.4ns ± 1% 49.2ns ± 1% -2.35% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader>/0/16384 50.9ns ± 2% 49.4ns ± 1% -2.81% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 50.9ns ± 2% 49.4ns ± 1% -2.91% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 50.2ns ± 0% 49.2ns ± 0% -2.04% (p=0.000 n=17+19) BM_HpackEncoderEncodeHeader>/0/16384 50.4ns ± 1% 49.2ns ± 1% -2.38% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader>/0/16384 50.3ns ± 0% 49.2ns ± 0% -2.06% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader/0/16384 91.7ns ± 1% 85.6ns ± 1% -6.64% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader>/0/16384 116ns ± 1% 112ns ± 1% -3.95% (p=0.000 n=19+18) BM_HpackEncoderEncodeHeader>/0/16384 122ns ± 0% 117ns ± 1% -3.63% (p=0.000 n=18+17) BM_HpackEncoderEncodeHeader>/0/16384 145ns ± 1% 140ns ± 0% -2.89% (p=0.000 n=18+18) BM_HpackEncoderEncodeHeader>/0/16384 233ns ± 1% 231ns ± 1% -1.14% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 472ns ± 1% 469ns ± 1% -0.64% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 93.2ns ± 1% 87.3ns ± 1% -6.41% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader>/0/16384 94.2ns ± 1% 88.0ns ± 1% -6.59% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader>/0/16384 94.1ns ± 2% 87.5ns ± 1% -6.98% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader>/0/16384 107ns ± 2% 102ns ± 4% -4.30% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader>/0/16384 106ns ± 1% 100ns ± 1% -5.64% (p=0.000 n=20+17) BM_HpackEncoderEncodeHeader/0/1 356ns ± 1% 355ns ± 1% -0.47% (p=0.001 n=20+18) BM_HpackEncoderEncodeHeader/0/16384 140ns ± 1% 128ns ± 1% -7.99% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader/0/16384 237ns ± 1% 218ns ± 1% -7.93% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader/0/16384 73.7ns ± 1% 69.7ns ± 1% -5.47% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader/1/16384 50.7ns ± 0% 49.0ns ± 2% -3.19% (p=0.000 n=18+19) --- src/core/ext/transport/chttp2/transport/hpack_encoder.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 359ad275bbb..3325c3ec24d 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -130,8 +130,9 @@ static void begin_frame(framer_state* st) { space to add at least about_to_add bytes -- finishes the current frame if needed */ static void ensure_space(framer_state* st, size_t need_bytes) { - if (st->output->length - st->output_length_at_start_of_frame + need_bytes <= - st->max_frame_size) { + if (GPR_LIKELY(st->output->length - st->output_length_at_start_of_frame + + need_bytes <= + st->max_frame_size)) { return; } finish_frame(st, 0, 0); From 913acf456b3f768880b017c15acbdec7489118bb Mon Sep 17 00:00:00 2001 From: Qixuan Li Date: Wed, 26 Jun 2019 22:32:33 +0000 Subject: [PATCH 497/676] fix minor nits --- test/cpp/interop/client_helper.cc | 2 +- test/cpp/interop/interop_client.cc | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index 2f312542b9b..a7279eb0092 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -107,7 +107,7 @@ std::shared_ptr CreateChannelForTestCase( : AccessTokenCredentials(GetOauth2AccessToken()); } else if (test_case == "pick_first_unary") { ChannelArguments channel_args; - // force using pick first policy + // allow the LB policy to be configured with service config channel_args.SetInt(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, 0); return CreateTestChannel(host_port, FLAGS_custom_credentials_type, FLAGS_server_host_override, !FLAGS_use_test_ca, diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 7c9a702a726..f474903331f 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -952,7 +952,7 @@ bool InteropClient::DoPickFirstUnary() { const int rpcCount = 100; SimpleRequest request; SimpleResponse response; - std::string first_server_id; + std::string server_id; request.set_fill_server_id(true); for (int i = 0; i < rpcCount; i++) { ClientContext context; @@ -961,11 +961,14 @@ bool InteropClient::DoPickFirstUnary() { return false; } if (i == 0) { - first_server_id = response.server_id(); - gpr_log(GPR_DEBUG, "first_user_id is %s", first_server_id.c_str()); + server_id = response.server_id(); continue; } - GPR_ASSERT(response.server_id() == first_server_id); + if (response.server_id() != server_id) { + gpr_log(GPR_ERROR, "#%d rpc hits server_id %s, expect server_id %s", i, + response.server_id().c_str(), server_id.c_str()); + return false; + } } gpr_log(GPR_DEBUG, "pick first unary successfully finished"); return true; From 7610817bc860d9f25fc76277684b6d6a90d9784e Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Wed, 26 Jun 2019 17:38:17 -0700 Subject: [PATCH 498/676] Also add the missing implementation of grpc_iomgr_run_in_background() for gevent. --- src/core/lib/iomgr/iomgr_custom.cc | 2 ++ src/core/lib/iomgr/iomgr_uv.cc | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index f5ac8a0670a..262417cf0d2 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -72,6 +72,8 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { return false; } + #ifdef GRPC_CUSTOM_SOCKET grpc_iomgr_platform_vtable* grpc_default_iomgr_platform_vtable() { return &vtable; diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc index d00bfa4d46e..4a984446dba 100644 --- a/src/core/lib/iomgr/iomgr_uv.cc +++ b/src/core/lib/iomgr/iomgr_uv.cc @@ -37,6 +37,4 @@ void grpc_set_default_iomgr_platform() { grpc_custom_iomgr_init(&grpc_uv_socket_vtable, &uv_resolver_vtable, &uv_timer_vtable, &uv_pollset_vtable); } - -bool grpc_iomgr_run_in_background() { return false; } #endif From b95bb89d13e8abd51c783a5dc8be82dc85653cf2 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Thu, 27 Jun 2019 09:55:03 -0700 Subject: [PATCH 499/676] Add TODO comment --- src/core/lib/gprpp/thd_posix.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 7415231e97f..99197cbbfa9 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -49,6 +49,8 @@ struct thd_arg { bool tracked; }; +// TODO(yunjiaw): move this to a function-level static, or remove the use of a +// non-constexpr initializer when possible const size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); size_t RoundUpToPageSize(size_t size) { From 424328b8e7c4c8a9b1b6b9d9ea607eab9787ae58 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Jun 2019 10:49:28 -0700 Subject: [PATCH 500/676] Resolve uninitialized warning --- src/core/lib/security/credentials/oauth2/oauth2_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 3d63ec12b49..5e0b9416e16 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -227,7 +227,7 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, void grpc_oauth2_token_fetcher_credentials::on_http_response( grpc_credentials_metadata_request* r, grpc_error* error) { grpc_mdelem access_token_md = GRPC_MDNULL; - grpc_millis token_lifetime; + grpc_millis token_lifetime = 0; grpc_credentials_status status = error == GRPC_ERROR_NONE ? grpc_oauth2_token_fetcher_credentials_parse_server_response( From dc858eea2578f856394f9fd2cd7f4ef2725266d9 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Jun 2019 14:19:15 -0400 Subject: [PATCH 501/676] Fix build failure in credential_test.cc --- test/core/security/credentials_test.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index cbce595c354..50340311fba 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -32,9 +32,9 @@ #include #include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" @@ -745,11 +745,11 @@ static void test_valid_sts_creds_options(void) { grpc_core::ValidateStsCredentialsOptions(&valid_options, &sts_url); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(sts_url != nullptr); - grpc_core::StringView host; - grpc_core::StringView port; - GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority, &host, &port)); - GPR_ASSERT(host.cmp("foo.com") == 0); - GPR_ASSERT(port.cmp("5555") == 0); + char* host; + char* port; + GPR_ASSERT(gpr_split_host_port(sts_url->authority, &host, &port)); + GPR_ASSERT(strcmp(host, "foo.com") == 0); + GPR_ASSERT(strcmp(port, "5555") == 0); grpc_uri_destroy(sts_url); } From 0d2c622f9ee747e7a21447c257e5f88825006216 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 27 Jun 2019 00:42:41 -0700 Subject: [PATCH 502/676] Fix DNS resolver cooldown --- CMakeLists.txt | 47 +++++++++++++-- Makefile | 58 +++++++++++++++---- build.yaml | 15 ++++- .../resolver/dns/c_ares/dns_resolver_ares.cc | 3 +- .../resolver/dns/native/dns_resolver.cc | 3 +- test/core/client_channel/resolvers/BUILD | 19 +++++- .../resolvers/dns_resolver_cooldown_test.cc | 46 ++++++++++++--- .../generated/sources_and_headers.json | 18 +++++- tools/run_tests/generated/tests.json | 32 +++++++++- 9 files changed, 208 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a34f9265256..6c1f8f24c57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -275,7 +275,8 @@ add_dependencies(buildtests_c compression_test) add_dependencies(buildtests_c concurrent_connectivity_test) add_dependencies(buildtests_c connection_refused_test) add_dependencies(buildtests_c dns_resolver_connectivity_test) -add_dependencies(buildtests_c dns_resolver_cooldown_test) +add_dependencies(buildtests_c dns_resolver_cooldown_using_ares_resolver_test) +add_dependencies(buildtests_c dns_resolver_cooldown_using_native_resolver_test) add_dependencies(buildtests_c dns_resolver_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c dualstack_socket_test) @@ -6874,12 +6875,12 @@ target_link_libraries(dns_resolver_connectivity_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(dns_resolver_cooldown_test +add_executable(dns_resolver_cooldown_using_ares_resolver_test test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc ) -target_include_directories(dns_resolver_cooldown_test +target_include_directories(dns_resolver_cooldown_using_ares_resolver_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -6892,7 +6893,7 @@ target_include_directories(dns_resolver_cooldown_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(dns_resolver_cooldown_test +target_link_libraries(dns_resolver_cooldown_using_ares_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -6901,8 +6902,42 @@ target_link_libraries(dns_resolver_cooldown_test # avoid dependency on libstdc++ if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(dns_resolver_cooldown_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(dns_resolver_cooldown_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + set_target_properties(dns_resolver_cooldown_using_ares_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dns_resolver_cooldown_using_ares_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(dns_resolver_cooldown_using_native_resolver_test + test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +) + + +target_include_directories(dns_resolver_cooldown_using_native_resolver_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(dns_resolver_cooldown_using_native_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(dns_resolver_cooldown_using_native_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dns_resolver_cooldown_using_native_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) endif() endif (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 9930fc35a25..52c175dab48 100644 --- a/Makefile +++ b/Makefile @@ -1015,7 +1015,8 @@ compression_test: $(BINDIR)/$(CONFIG)/compression_test concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test -dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test +dns_resolver_cooldown_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test +dns_resolver_cooldown_using_native_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test @@ -1446,7 +1447,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/concurrent_connectivity_test \ $(BINDIR)/$(CONFIG)/connection_refused_test \ $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \ - $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \ + $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test \ + $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test \ $(BINDIR)/$(CONFIG)/dns_resolver_test \ $(BINDIR)/$(CONFIG)/dualstack_socket_test \ $(BINDIR)/$(CONFIG)/endpoint_pair_test \ @@ -1983,8 +1985,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_connectivity_test" $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 ) - $(E) "[RUN] Testing dns_resolver_cooldown_test" - $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test || ( echo test dns_resolver_cooldown_test failed ; exit 1 ) + $(E) "[RUN] Testing dns_resolver_cooldown_using_ares_resolver_test" + $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test || ( echo test dns_resolver_cooldown_using_ares_resolver_test failed ; exit 1 ) + $(E) "[RUN] Testing dns_resolver_cooldown_using_native_resolver_test" + $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test || ( echo test dns_resolver_cooldown_using_native_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing dns_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/dns_resolver_test || ( echo test dns_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing dualstack_socket_test" @@ -9638,34 +9642,66 @@ endif endif -DNS_RESOLVER_COOLDOWN_TEST_SRC = \ +DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC = \ test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \ -DNS_RESOLVER_COOLDOWN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_TEST_SRC)))) +DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_ares_resolver_test endif $(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_dns_resolver_cooldown_test: $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep) +deps_dns_resolver_cooldown_using_ares_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(DNS_RESOLVER_COOLDOWN_TEST_OBJS:.o=.dep) +-include $(DNS_RESOLVER_COOLDOWN_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) +endif +endif + + +DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC = \ + test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc \ + +DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_using_native_resolver_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/client_channel/resolvers/dns_resolver_cooldown_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_dns_resolver_cooldown_using_native_resolver_test: $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(DNS_RESOLVER_COOLDOWN_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) endif endif diff --git a/build.yaml b/build.yaml index dad2146bd1c..a5b271ebad2 100644 --- a/build.yaml +++ b/build.yaml @@ -2399,7 +2399,7 @@ targets: - gpr exclude_iomgrs: - uv -- name: dns_resolver_cooldown_test +- name: dns_resolver_cooldown_using_ares_resolver_test build: test language: c src: @@ -2408,6 +2408,19 @@ targets: - grpc_test_util - grpc - gpr + args: + - --resolver=ares +- name: dns_resolver_cooldown_using_native_resolver_test + build: test + language: c + src: + - test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc + deps: + - grpc_test_util + - grpc + - gpr + args: + - --resolver=native - name: dns_resolver_test build: test language: c diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 32a339af359..24b6537b7ca 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -401,7 +401,8 @@ void AresDnsResolver::MaybeStartResolvingLocked() { // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); - grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, + grpc_timer_init(&next_resolution_timer_, + ExecCtx::Get()->Now() + ms_until_next_resolution, &on_next_resolution_); return; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 5ab75d02793..6a2439a5d35 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -230,7 +230,8 @@ void NativeDnsResolver::MaybeStartResolvingLocked() { // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); - grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, + grpc_timer_init(&next_resolution_timer_, + ExecCtx::Get()->Now() + ms_until_next_resolution, &on_next_resolution_); return; } diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD index 3dbee5c9e6d..e5882069cd4 100644 --- a/test/core/client_channel/resolvers/BUILD +++ b/test/core/client_channel/resolvers/BUILD @@ -19,9 +19,26 @@ grpc_package(name = "test/core/client_channel_resolvers") licenses(["notice"]) # Apache v2 grpc_cc_test( - name = "dns_resolver_connectivity_test", + name = "dns_resolver_connectivity_using_ares_resolver_test", srcs = ["dns_resolver_connectivity_test.cc"], language = "C++", + args = [ + "--resolver=ares", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "dns_resolver_connectivity_using_native_resolver_test", + srcs = ["dns_resolver_connectivity_test.cc"], + language = "C++", + args = [ + "--resolver=native", + ], deps = [ "//:gpr", "//:grpc", diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 7b3a4589f5b..683d02079c3 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -101,12 +101,16 @@ static grpc_ares_request* test_dns_lookup_ares_locked( addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; + grpc_millis now = + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + gpr_log(GPR_DEBUG, + "last_resolution_time:%" PRId64 " now:%" PRId64 + " min_time_between:%d", + last_resolution_time, now, kMinResolutionPeriodForCheckMs); if (last_resolution_time == 0) { last_resolution_time = grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); } else { - grpc_millis now = - grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodForCheckMs); last_resolution_time = now; } @@ -212,19 +216,46 @@ struct OnResolutionCallbackArg { // Set to true by the last callback in the resolution chain. static bool g_all_callbacks_invoked; +// It's interesting to run a few rounds of this test because as +// we run more rounds, the base starting time +// (i.e. ExecCtx g_start_time) gets further and further away +// from "Now()". Thus the more rounds ran, the more highlighted the +// difference is between absolute and relative times values. +static void on_fourth_resolution(OnResolutionCallbackArg* cb_arg) { + gpr_log(GPR_INFO, "4th: g_resolution_count: %d", g_resolution_count); + GPR_ASSERT(g_resolution_count == 4); + cb_arg->resolver.reset(); + gpr_atm_rel_store(&g_iomgr_args.done_atm, 1); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); + grpc_core::Delete(cb_arg); + g_all_callbacks_invoked = true; +} + +static void on_third_resolution(OnResolutionCallbackArg* cb_arg) { + gpr_log(GPR_INFO, "3rd: g_resolution_count: %d", g_resolution_count); + GPR_ASSERT(g_resolution_count == 3); + cb_arg->result_handler->SetCallback(on_fourth_resolution, cb_arg); + cb_arg->resolver->RequestReresolutionLocked(); + gpr_mu_lock(g_iomgr_args.mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); + gpr_mu_unlock(g_iomgr_args.mu); +} + static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); // The resolution callback was not invoked until new data was // available, which was delayed until after the cooldown period. GPR_ASSERT(g_resolution_count == 2); - cb_arg->resolver.reset(); - gpr_atm_rel_store(&g_iomgr_args.done_atm, 1); + cb_arg->result_handler->SetCallback(on_third_resolution, cb_arg); + cb_arg->resolver->RequestReresolutionLocked(); gpr_mu_lock(g_iomgr_args.mu); GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); gpr_mu_unlock(g_iomgr_args.mu); - grpc_core::Delete(cb_arg); - g_all_callbacks_invoked = true; } static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { @@ -243,9 +274,7 @@ static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { static void start_test_under_combiner(void* arg, grpc_error* error) { OnResolutionCallbackArg* res_cb_arg = static_cast(arg); - res_cb_arg->result_handler = grpc_core::New(); - grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, 0); @@ -300,7 +329,6 @@ int main(int argc, char** argv) { grpc_set_resolver_impl(&test_resolver); test_cooldown(); - { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8765f216dab..f99c64e19a1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -392,7 +392,23 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "dns_resolver_cooldown_test", + "name": "dns_resolver_cooldown_using_ares_resolver_test", + "src": [ + "test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "dns_resolver_cooldown_using_native_resolver_test", "src": [ "test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc" ], diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 625d3bd295f..89d68a64628 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -484,7 +484,35 @@ "uses_polling": true }, { - "args": [], + "args": [ + "--resolver=ares" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "dns_resolver_cooldown_using_ares_resolver_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, + { + "args": [ + "--resolver=native" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -498,7 +526,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "dns_resolver_cooldown_test", + "name": "dns_resolver_cooldown_using_native_resolver_test", "platforms": [ "linux", "mac", From 36339f4032f7a2a2800c5c650b79a1f18e351e2e Mon Sep 17 00:00:00 2001 From: nanahpang <31627465+nanahpang@users.noreply.github.com> Date: Thu, 27 Jun 2019 16:25:27 -0700 Subject: [PATCH 503/676] fix typo "transfered" to "transferred" find the typo during import and create this pr to sync up --- src/core/lib/security/credentials/oauth2/oauth2_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 5e0b9416e16..06fa8bbdb4b 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -520,7 +520,7 @@ grpc_error* LoadTokenFile(const char* path, gpr_slice* token) { class StsTokenFetcherCredentials : public grpc_oauth2_token_fetcher_credentials { public: - StsTokenFetcherCredentials(grpc_uri* sts_url, // Ownership transfered. + StsTokenFetcherCredentials(grpc_uri* sts_url, // Ownership transferred. const grpc_sts_credentials_options* options) : sts_url_(sts_url), resource_(gpr_strdup(options->resource)), From 80d1aec0218b3dc72acb23c838deaa0d7a10cb1a Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 27 Jun 2019 14:54:51 -0700 Subject: [PATCH 504/676] Codegen optimizations for hpack_parser on_hdr. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the log statements for on_hdr clobber some registers even if it is disabled by default. Additionally, the no-error path is doing some unnecessary jumps. This PR separates out and un-inlines the logging code, and marks the no-error case as likely to occur. This results in slightly faster hpack_parsing, e.g.: BM_HpackParserParseHeader 23.8ns ± 0% 19.8ns ± 0% -16.81% (p=0.000 n=17+17) BM_HpackParserParseHeader 160ns ± 0% 154ns ± 0% -3.18% (p=0.000 n=19+20) BM_HpackParserParseHeader 216ns ± 1% 214ns ± 2% -0.70% (p=0.004 n=18+18) BM_HpackParserParseHeader 35.4ns ± 0% 34.4ns ± 0% -2.93% (p=0.000 n=16+16) BM_HpackParserParseHeader 140ns ± 0% 130ns ± 0% -7.06% (p=0.000 n=17+18) BM_HpackParserParseHeader 644ns ± 1% 636ns ± 2% -1.29% (p=0.003 n=17+20) BM_HpackParserParseHeader 49.1ns ± 0% 38.7ns ± 0% -21.13% (p=0.000 n=19+18) BM_HpackParserParseHeader 47.1ns ± 0% 43.2ns ± 0% -8.17% (p=0.000 n=20+19) BM_HpackParserParseHeader 452ns ± 1% 417ns ± 1% -7.86% (p=0.000 n=20+20) BM_HpackParserParseHeader 1.06µs ± 1% 1.02µs ± 2% -3.42% (p=0.000 n=19+20) BM_HpackParserParseHeader 156ns ± 0% 142ns ± 1% -9.08% (p=0.000 n=17+19) BM_HpackParserParseHeader 117ns ± 0% 113ns ± 1% -3.98% (p=0.000 n=20+20) --- .../chttp2/transport/hpack_parser.cc | 96 +++++++++---------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 8db0c96cc52..efbd997e994 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -622,33 +622,37 @@ static const uint8_t inverse_base64[256] = { 255, }; +static void GPR_ATTRIBUTE_NOINLINE on_hdr_log(grpc_mdelem md) { + char* k = grpc_slice_to_c_string(GRPC_MDKEY(md)); + char* v = nullptr; + if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) { + v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX); + } else { + v = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + } + gpr_log( + GPR_INFO, + "Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d", + k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md), + grpc_slice_is_interned(GRPC_MDKEY(md)), + grpc_slice_is_interned(GRPC_MDVALUE(md))); + gpr_free(k); + gpr_free(v); +} + /* emission helpers */ -static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md, - int add_to_table) { +template +static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md) { if (GRPC_TRACE_FLAG_ENABLED(grpc_http_trace)) { - char* k = grpc_slice_to_c_string(GRPC_MDKEY(md)); - char* v = nullptr; - if (grpc_is_binary_header_internal(GRPC_MDKEY(md))) { - v = grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX); - } else { - v = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - } - gpr_log( - GPR_INFO, - "Decode: '%s: %s', elem_interned=%d [%d], k_interned=%d, v_interned=%d", - k, v, GRPC_MDELEM_IS_INTERNED(md), GRPC_MDELEM_STORAGE(md), - grpc_slice_is_interned(GRPC_MDKEY(md)), - grpc_slice_is_interned(GRPC_MDVALUE(md))); - gpr_free(k); - gpr_free(v); + on_hdr_log(md); } - if (add_to_table) { - GPR_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED || - GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC); + if (do_add) { + GPR_DEBUG_ASSERT(GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_INTERNED || + GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC); grpc_error* err = grpc_chttp2_hptbl_add(&p->table, md); - if (err != GRPC_ERROR_NONE) return err; + if (GPR_UNLIKELY(err != GRPC_ERROR_NONE)) return err; } - if (p->on_header == nullptr) { + if (GPR_UNLIKELY(p->on_header == nullptr)) { GRPC_MDELEM_UNREF(md); return GRPC_ERROR_CREATE_FROM_STATIC_STRING("on_header callback not set"); } @@ -765,7 +769,7 @@ static grpc_error* finish_indexed_field(grpc_chttp2_hpack_parser* p, } GRPC_MDELEM_REF(md); GRPC_STATS_INC_HPACK_RECV_INDEXED(); - grpc_error* err = on_hdr(p, md, 0); + grpc_error* err = on_hdr(p, md); if (err != GRPC_ERROR_NONE) return err; return parse_begin(p, cur, end); } @@ -798,11 +802,9 @@ static grpc_error* finish_lithdr_incidx(grpc_chttp2_hpack_parser* p, grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, true)), - 1); + grpc_error* err = on_hdr( + p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(p, &p->value, true))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } @@ -813,10 +815,8 @@ static grpc_error* finish_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, const uint8_t* end) { GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V(); grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, true)), - 1); + on_hdr(p, grpc_mdelem_from_slices(take_string(p, &p->key, true), + take_string(p, &p->value, true))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } @@ -865,11 +865,9 @@ static grpc_error* finish_lithdr_notidx(grpc_chttp2_hpack_parser* p, grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, false)), - 0); + grpc_error* err = on_hdr( + p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(p, &p->value, false))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } @@ -879,11 +877,9 @@ static grpc_error* finish_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, false)), - 0); + grpc_error* err = on_hdr( + p, grpc_mdelem_from_slices(take_string(p, &p->key, true), + take_string(p, &p->value, false))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } @@ -932,11 +928,9 @@ static grpc_error* finish_lithdr_nvridx(grpc_chttp2_hpack_parser* p, grpc_mdelem md = grpc_chttp2_hptbl_lookup(&p->table, p->index); GPR_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), - take_string(p, &p->value, false)), - 0); + grpc_error* err = on_hdr( + p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), + take_string(p, &p->value, false))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } @@ -946,11 +940,9 @@ static grpc_error* finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V(); - grpc_error* err = - on_hdr(p, - grpc_mdelem_from_slices(take_string(p, &p->key, true), - take_string(p, &p->value, false)), - 0); + grpc_error* err = on_hdr( + p, grpc_mdelem_from_slices(take_string(p, &p->key, true), + take_string(p, &p->value, false))); if (err != GRPC_ERROR_NONE) return parse_error(p, cur, end, err); return parse_begin(p, cur, end); } From dbf88dd66f0c45f2f3ce3d5209d9cd4ef180367d Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Jun 2019 11:15:31 -0400 Subject: [PATCH 505/676] Revert "Revert "Introduce string_view and use it for gpr_split_host_port."" This reverts commit 80c177d4c40ef85eb8ec37f9d4bfa030361958e1. --- BUILD | 8 +- BUILD.gn | 8 +- CMakeLists.txt | 44 ++++- Makefile | 54 +++++- build.yaml | 20 ++- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 6 +- gRPC-Core.podspec | 8 +- grpc.gemspec | 5 +- grpc.gyp | 2 +- package.xml | 5 +- .../ext/filters/client_channel/http_proxy.cc | 19 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 1 - .../client_channel/lb_policy/xds/xds.cc | 1 - .../filters/client_channel/parse_address.cc | 55 +++--- .../resolver/dns/c_ares/dns_resolver_ares.cc | 1 - .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 95 +++++----- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 1 - .../dns/c_ares/grpc_ares_wrapper_windows.cc | 1 - .../resolver/dns/native/dns_resolver.cc | 1 - .../resolver/fake/fake_resolver.cc | 1 - .../resolver/sockaddr/sockaddr_resolver.cc | 1 - .../transport/chttp2/server/chttp2_server.cc | 1 - .../transport/chttp2/transport/frame_data.cc | 8 +- .../cronet/transport/cronet_transport.cc | 1 - src/core/lib/channel/channelz.cc | 15 +- src/core/lib/gpr/host_port.cc | 98 ----------- src/core/lib/gpr/string.cc | 9 +- src/core/lib/gpr/string.h | 1 + src/core/lib/gprpp/host_port.cc | 97 +++++++++++ src/core/lib/{gpr => gprpp}/host_port.h | 38 ++-- src/core/lib/gprpp/string_view.h | 143 +++++++++++++++ .../lib/http/httpcli_security_connector.cc | 4 +- src/core/lib/iomgr/resolve_address_custom.cc | 35 ++-- src/core/lib/iomgr/resolve_address_posix.cc | 18 +- src/core/lib/iomgr/resolve_address_windows.cc | 14 +- src/core/lib/iomgr/sockaddr_utils.cc | 8 +- .../lib/iomgr/socket_utils_common_posix.cc | 1 - src/core/lib/iomgr/tcp_client_cfstream.cc | 13 +- .../alts/alts_security_connector.cc | 5 +- .../fake/fake_security_connector.cc | 46 +++-- .../local/local_security_connector.cc | 5 +- .../security_connector/security_connector.cc | 2 +- .../security_connector/security_connector.h | 2 +- .../ssl/ssl_security_connector.cc | 38 ++-- .../security/security_connector/ssl_utils.cc | 57 +++--- .../security/security_connector/ssl_utils.h | 19 +- .../tls/spiffe_security_connector.cc | 36 ++-- .../tls/spiffe_security_connector.h | 7 +- .../security/transport/client_auth_filter.cc | 3 +- .../alts/handshaker/alts_tsi_handshaker.cc | 1 - src/core/tsi/ssl_transport_security.cc | 78 ++++----- src/core/tsi/ssl_transport_security.h | 3 +- .../CronetTests/CoreCronetEnd2EndTests.mm | 21 ++- .../tests/CronetTests/CronetUnitTests.mm | 14 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- test/core/bad_ssl/bad_ssl_test.cc | 8 +- .../parse_address_with_named_scope_id_test.cc | 17 +- test/core/end2end/bad_server_response_test.cc | 11 +- test/core/end2end/connection_refused_test.cc | 12 +- test/core/end2end/dualstack_socket_test.cc | 25 ++- test/core/end2end/fixtures/h2_census.cc | 22 ++- test/core/end2end/fixtures/h2_compress.cc | 33 ++-- test/core/end2end/fixtures/h2_fakesec.cc | 23 ++- test/core/end2end/fixtures/h2_full+pipe.cc | 21 ++- test/core/end2end/fixtures/h2_full+trace.cc | 21 ++- .../end2end/fixtures/h2_full+workarounds.cc | 24 ++- test/core/end2end/fixtures/h2_full.cc | 21 ++- test/core/end2end/fixtures/h2_http_proxy.cc | 27 ++- test/core/end2end/fixtures/h2_local_ipv4.cc | 4 +- test/core/end2end/fixtures/h2_local_ipv6.cc | 4 +- test/core/end2end/fixtures/h2_local_uds.cc | 8 +- test/core/end2end/fixtures/h2_oauth2.cc | 25 ++- test/core/end2end/fixtures/h2_proxy.cc | 1 - test/core/end2end/fixtures/h2_spiffe.cc | 25 +-- test/core/end2end/fixtures/h2_ssl.cc | 22 ++- .../end2end/fixtures/h2_ssl_cred_reload.cc | 24 ++- test/core/end2end/fixtures/h2_ssl_proxy.cc | 1 - test/core/end2end/fixtures/h2_uds.cc | 1 - .../end2end/fixtures/http_proxy_fixture.cc | 14 +- test/core/end2end/fixtures/inproc.cc | 1 - test/core/end2end/fixtures/local_util.cc | 15 +- test/core/end2end/fixtures/local_util.h | 6 +- test/core/end2end/fixtures/proxy.cc | 29 ++-- test/core/end2end/h2_ssl_cert_test.cc | 22 ++- .../core/end2end/h2_ssl_session_reuse_test.cc | 15 +- .../end2end/invalid_call_argument_test.cc | 15 +- test/core/fling/fling_stream_test.cc | 11 +- test/core/fling/fling_test.cc | 12 +- test/core/fling/server.cc | 12 +- test/core/gpr/BUILD | 10 -- test/core/gprpp/BUILD | 23 +++ test/core/{gpr => gprpp}/host_port_test.cc | 11 +- test/core/gprpp/string_view_test.cc | 163 ++++++++++++++++++ test/core/memory_usage/memory_usage_test.cc | 11 +- test/core/memory_usage/server.cc | 12 +- ...num_external_connectivity_watchers_test.cc | 21 +-- .../surface/sequential_connectivity_test.cc | 11 +- test/core/surface/server_chttp2_test.cc | 12 +- test/core/surface/server_test.cc | 14 +- test/core/util/reconnect_server.cc | 1 - test/core/util/test_tcp_server.cc | 1 - test/cpp/interop/interop_test.cc | 1 - test/cpp/naming/address_sorting_test.cc | 18 +- test/cpp/naming/cancel_ares_query_test.cc | 1 - test/cpp/naming/resolver_component_test.cc | 16 +- test/cpp/qps/client_sync.cc | 1 - test/cpp/qps/driver.cc | 22 +-- test/cpp/qps/qps_worker.cc | 9 +- test/cpp/qps/server_async.cc | 9 +- test/cpp/qps/server_callback.cc | 9 +- test/cpp/qps/server_sync.cc | 9 +- tools/doxygen/Doxyfile.c++.internal | 3 +- tools/doxygen/Doxyfile.core.internal | 5 +- .../generated/sources_and_headers.json | 28 ++- tools/run_tests/generated/tests.json | 24 +++ 117 files changed, 1280 insertions(+), 881 deletions(-) delete mode 100644 src/core/lib/gpr/host_port.cc create mode 100644 src/core/lib/gprpp/host_port.cc rename src/core/lib/{gpr => gprpp}/host_port.h (51%) create mode 100644 src/core/lib/gprpp/string_view.h rename test/core/{gpr => gprpp}/host_port_test.cc (86%) create mode 100644 test/core/gprpp/string_view_test.cc diff --git a/BUILD b/BUILD index 87d3b978358..f7c97beaaaf 100644 --- a/BUILD +++ b/BUILD @@ -559,7 +559,6 @@ grpc_cc_library( "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -586,6 +585,7 @@ grpc_cc_library( "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -595,7 +595,6 @@ grpc_cc_library( "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -612,14 +611,16 @@ grpc_cc_library( "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", - "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", "src/core/lib/gprpp/pair.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", @@ -628,6 +629,7 @@ grpc_cc_library( public_hdrs = GPR_PUBLIC_HDRS, deps = [ "gpr_codegen", + "grpc_codegen", ], ) diff --git a/BUILD.gn b/BUILD.gn index fc9fa8dc3d0..08625e9bd12 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -141,8 +141,6 @@ config("grpc_config") { "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -189,6 +187,8 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.cc", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -480,6 +480,7 @@ config("grpc_config") { "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.cc", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.cc", @@ -1172,7 +1173,6 @@ config("grpc_config") { "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -1194,6 +1194,7 @@ config("grpc_config") { "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/inlined_vector.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", @@ -1203,6 +1204,7 @@ config("grpc_config") { "src/core/lib/gprpp/pair.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/gprpp/sync.h", "src/core/lib/gprpp/thd.h", "src/core/lib/http/format_request.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index ce16506ab62..261a561918f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -713,6 +713,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx streaming_throughput_test) endif() add_dependencies(buildtests_cxx stress_test) +add_dependencies(buildtests_cxx string_view_test) add_dependencies(buildtests_cxx thread_manager_test) add_dependencies(buildtests_cxx thread_stress_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -861,7 +862,6 @@ add_library(gpr src/core/lib/gpr/env_linux.cc src/core/lib/gpr/env_posix.cc src/core/lib/gpr/env_windows.cc - src/core/lib/gpr/host_port.cc src/core/lib/gpr/log.cc src/core/lib/gpr/log_android.cc src/core/lib/gpr/log_linux.cc @@ -888,6 +888,7 @@ add_library(gpr src/core/lib/gprpp/arena.cc src/core/lib/gprpp/fork.cc src/core/lib/gprpp/global_config_env.cc + src/core/lib/gprpp/host_port.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -7509,7 +7510,7 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) add_executable(gpr_host_port_test - test/core/gpr/host_port_test.cc + test/core/gprpp/host_port_test.cc ) @@ -16642,6 +16643,45 @@ target_link_libraries(stress_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(string_view_test + test/core/gprpp/string_view_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(string_view_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(string_view_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index e2e8aa60488..d19adcabec9 100644 --- a/Makefile +++ b/Makefile @@ -1278,6 +1278,7 @@ status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test status_util_test: $(BINDIR)/$(CONFIG)/status_util_test streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test +string_view_test: $(BINDIR)/$(CONFIG)/string_view_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test time_change_test: $(BINDIR)/$(CONFIG)/time_change_test @@ -1744,6 +1745,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ + $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -1907,6 +1909,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/status_util_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ + $(BINDIR)/$(CONFIG)/string_view_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ $(BINDIR)/$(CONFIG)/time_change_test \ @@ -2433,6 +2436,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 ) $(E) "[RUN] Testing streaming_throughput_test" $(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 ) + $(E) "[RUN] Testing string_view_test" + $(Q) $(BINDIR)/$(CONFIG)/string_view_test || ( echo test string_view_test failed ; exit 1 ) $(E) "[RUN] Testing thread_manager_test" $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(E) "[RUN] Testing thread_stress_test" @@ -3379,7 +3384,6 @@ LIBGPR_SRC = \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ - src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -3406,6 +3410,7 @@ LIBGPR_SRC = \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ + src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -10221,7 +10226,7 @@ endif GPR_HOST_PORT_TEST_SRC = \ - test/core/gpr/host_port_test.cc \ + test/core/gprpp/host_port_test.cc \ GPR_HOST_PORT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_HOST_PORT_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -10241,7 +10246,7 @@ $(BINDIR)/$(CONFIG)/gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS) $(LIBDIR)/$(C endif -$(OBJDIR)/$(CONFIG)/test/core/gpr/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a +$(OBJDIR)/$(CONFIG)/test/core/gprpp/host_port_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a deps_gpr_host_port_test: $(GPR_HOST_PORT_TEST_OBJS:.o=.dep) @@ -19669,6 +19674,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/src/proto/grpc/tes $(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc +STRING_VIEW_TEST_SRC = \ + test/core/gprpp/string_view_test.cc \ + +STRING_VIEW_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRING_VIEW_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/string_view_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.5.0+. + +$(BINDIR)/$(CONFIG)/string_view_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/string_view_test: $(PROTOBUF_DEP) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(STRING_VIEW_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/string_view_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/string_view_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_string_view_test: $(STRING_VIEW_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(STRING_VIEW_TEST_OBJS:.o=.dep) +endif +endif + + THREAD_MANAGER_TEST_SRC = \ test/cpp/thread_manager/thread_manager_test.cc \ diff --git a/build.yaml b/build.yaml index 5b9a8c1594e..ff27f1fb31f 100644 --- a/build.yaml +++ b/build.yaml @@ -122,7 +122,6 @@ filegroups: - src/core/lib/gpr/env_linux.cc - src/core/lib/gpr/env_posix.cc - src/core/lib/gpr/env_windows.cc - - src/core/lib/gpr/host_port.cc - src/core/lib/gpr/log.cc - src/core/lib/gpr/log_android.cc - src/core/lib/gpr/log_linux.cc @@ -149,6 +148,7 @@ filegroups: - src/core/lib/gprpp/arena.cc - src/core/lib/gprpp/fork.cc - src/core/lib/gprpp/global_config_env.cc + - src/core/lib/gprpp/host_port.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -178,7 +178,6 @@ filegroups: - src/core/lib/gpr/alloc.h - src/core/lib/gpr/arena.h - src/core/lib/gpr/env.h - - src/core/lib/gpr/host_port.h - src/core/lib/gpr/mpscq.h - src/core/lib/gpr/murmur_hash.h - src/core/lib/gpr/spinlock.h @@ -199,6 +198,7 @@ filegroups: - src/core/lib/gprpp/global_config_custom.h - src/core/lib/gprpp/global_config_env.h - src/core/lib/gprpp/global_config_generic.h + - src/core/lib/gprpp/host_port.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h @@ -444,6 +444,7 @@ filegroups: - src/core/lib/gprpp/orphanable.h - src/core/lib/gprpp/ref_counted.h - src/core/lib/gprpp/ref_counted_ptr.h + - src/core/lib/gprpp/string_view.h - src/core/lib/http/format_request.h - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h @@ -2626,7 +2627,7 @@ targets: build: test language: c src: - - test/core/gpr/host_port_test.cc + - test/core/gprpp/host_port_test.cc deps: - gpr - grpc_test_util_unsecure @@ -5761,6 +5762,19 @@ targets: - grpc - gpr - grpc++_test_config +- name: string_view_test + gtest: true + build: test + language: c++ + src: + - test/core/gprpp/string_view_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: thread_manager_test build: test language: c++ diff --git a/config.m4 b/config.m4 index bb30be56910..99d49d391b4 100644 --- a/config.m4 +++ b/config.m4 @@ -53,7 +53,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ - src/core/lib/gpr/host_port.cc \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -80,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/global_config_env.cc \ + src/core/lib/gprpp/host_port.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ diff --git a/config.w32 b/config.w32 index c9faa8d9ac8..f6c6b4fde10 100644 --- a/config.w32 +++ b/config.w32 @@ -28,7 +28,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gpr\\env_linux.cc " + "src\\core\\lib\\gpr\\env_posix.cc " + "src\\core\\lib\\gpr\\env_windows.cc " + - "src\\core\\lib\\gpr\\host_port.cc " + "src\\core\\lib\\gpr\\log.cc " + "src\\core\\lib\\gpr\\log_android.cc " + "src\\core\\lib\\gpr\\log_linux.cc " + @@ -55,6 +54,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gprpp\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + "src\\core\\lib\\gprpp\\global_config_env.cc " + + "src\\core\\lib\\gprpp\\host_port.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6fc97c6135e..a09173dc8f0 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -262,7 +262,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -283,6 +282,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -445,6 +445,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -592,7 +593,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -613,6 +613,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -649,6 +650,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2e34e8d7573..6255fdfd0ce 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -191,7 +191,6 @@ Pod::Spec.new do |s| ss.source_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -212,6 +211,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -228,7 +228,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -255,6 +254,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -414,6 +414,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', @@ -884,7 +885,6 @@ Pod::Spec.new do |s| ss.private_header_files = 'src/core/lib/gpr/alloc.h', 'src/core/lib/gpr/arena.h', 'src/core/lib/gpr/env.h', - 'src/core/lib/gpr/host_port.h', 'src/core/lib/gpr/mpscq.h', 'src/core/lib/gpr/murmur_hash.h', 'src/core/lib/gpr/spinlock.h', @@ -905,6 +905,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/global_config_custom.h', 'src/core/lib/gprpp/global_config_env.h', 'src/core/lib/gprpp/global_config_generic.h', + 'src/core/lib/gprpp/host_port.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -1067,6 +1068,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', + 'src/core/lib/gprpp/string_view.h', 'src/core/lib/http/format_request.h', 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', diff --git a/grpc.gemspec b/grpc.gemspec index 11469a3ec5c..a1051fd4685 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -85,7 +85,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/alloc.h ) s.files += %w( src/core/lib/gpr/arena.h ) s.files += %w( src/core/lib/gpr/env.h ) - s.files += %w( src/core/lib/gpr/host_port.h ) s.files += %w( src/core/lib/gpr/mpscq.h ) s.files += %w( src/core/lib/gpr/murmur_hash.h ) s.files += %w( src/core/lib/gpr/spinlock.h ) @@ -106,6 +105,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/global_config_custom.h ) s.files += %w( src/core/lib/gprpp/global_config_env.h ) s.files += %w( src/core/lib/gprpp/global_config_generic.h ) + s.files += %w( src/core/lib/gprpp/host_port.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) @@ -122,7 +122,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/env_linux.cc ) s.files += %w( src/core/lib/gpr/env_posix.cc ) s.files += %w( src/core/lib/gpr/env_windows.cc ) - s.files += %w( src/core/lib/gpr/host_port.cc ) s.files += %w( src/core/lib/gpr/log.cc ) s.files += %w( src/core/lib/gpr/log_android.cc ) s.files += %w( src/core/lib/gpr/log_linux.cc ) @@ -149,6 +148,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) s.files += %w( src/core/lib/gprpp/global_config_env.cc ) + s.files += %w( src/core/lib/gprpp/host_port.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) @@ -348,6 +348,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/orphanable.h ) s.files += %w( src/core/lib/gprpp/ref_counted.h ) s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h ) + s.files += %w( src/core/lib/gprpp/string_view.h ) s.files += %w( src/core/lib/http/format_request.h ) s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) diff --git a/grpc.gyp b/grpc.gyp index 6268bed7bb0..784279301d3 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -226,7 +226,6 @@ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -253,6 +252,7 @@ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/package.xml b/package.xml index 616e1ece20e..388e8d8620a 100644 --- a/package.xml +++ b/package.xml @@ -90,7 +90,6 @@ - @@ -111,6 +110,7 @@ + @@ -127,7 +127,6 @@ - @@ -154,6 +153,7 @@ + @@ -353,6 +353,7 @@ + diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc index 8951a2920c4..9e60a553ceb 100644 --- a/src/core/ext/filters/client_channel/http_proxy.cc +++ b/src/core/ext/filters/client_channel/http_proxy.cc @@ -31,8 +31,8 @@ #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/slice/b64.h" #include "src/core/lib/uri/uri_parser.h" @@ -126,17 +126,18 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, if (no_proxy_str != nullptr) { static const char* NO_PROXY_SEPARATOR = ","; bool use_proxy = true; - char* server_host; - char* server_port; - if (!gpr_split_host_port(uri->path[0] == '/' ? uri->path + 1 : uri->path, - &server_host, &server_port)) { + grpc_core::UniquePtr server_host; + grpc_core::UniquePtr server_port; + if (!grpc_core::SplitHostPort( + uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host, + &server_port)) { gpr_log(GPR_INFO, "unable to split host and port, not checking no_proxy list for " "host '%s'", server_uri); gpr_free(no_proxy_str); } else { - size_t uri_len = strlen(server_host); + size_t uri_len = strlen(server_host.get()); char** no_proxy_hosts; size_t num_no_proxy_hosts; gpr_string_split(no_proxy_str, NO_PROXY_SEPARATOR, &no_proxy_hosts, @@ -145,8 +146,8 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, char* no_proxy_entry = no_proxy_hosts[i]; size_t no_proxy_len = strlen(no_proxy_entry); if (no_proxy_len <= uri_len && - gpr_stricmp(no_proxy_entry, &server_host[uri_len - no_proxy_len]) == - 0) { + gpr_stricmp(no_proxy_entry, + &(server_host.get()[uri_len - no_proxy_len])) == 0) { gpr_log(GPR_INFO, "not using proxy for host in no_proxy list '%s'", server_uri); use_proxy = false; @@ -157,8 +158,6 @@ static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper, gpr_free(no_proxy_hosts[i]); } gpr_free(no_proxy_hosts); - gpr_free(server_host); - gpr_free(server_port); gpr_free(no_proxy_str); if (!use_proxy) goto no_use_proxy; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 2f3516066da..71e8e248770 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -84,7 +84,6 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e5c27fe67a4..ca9ea9e31cc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -84,7 +84,6 @@ #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/map.h" diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index c5e1ed811bc..fbfbb4445f3 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -33,8 +33,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #ifdef GRPC_POSIX_SOCKET #include @@ -73,9 +73,9 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - char* host; - char* port; - if (!gpr_split_host_port(hostport, &host, &port)) { + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + if (!grpc_core::SplitHostPort(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -86,8 +86,10 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, addr->len = static_cast(sizeof(grpc_sockaddr_in)); grpc_sockaddr_in* in = reinterpret_cast(addr->addr); in->sin_family = GRPC_AF_INET; - if (grpc_inet_pton(GRPC_AF_INET, host, &in->sin_addr) == 0) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host); + if (grpc_inet_pton(GRPC_AF_INET, host.get(), &in->sin_addr) == 0) { + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host.get()); + } goto done; } // Parse port. @@ -96,15 +98,14 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port); + if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port.get()); goto done; } in->sin_port = grpc_htons(static_cast(port_num)); success = true; done: - gpr_free(host); - gpr_free(port); return success; } @@ -124,9 +125,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors) { bool success = false; // Split host and port. - char* host; - char* port; - if (!gpr_split_host_port(hostport, &host, &port)) { + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + if (!grpc_core::SplitHostPort(hostport, &host, &port)) { if (log_errors) { gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport); } @@ -138,11 +139,12 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, grpc_sockaddr_in6* in6 = reinterpret_cast(addr->addr); in6->sin6_family = GRPC_AF_INET6; // Handle the RFC6874 syntax for IPv6 zone identifiers. - char* host_end = static_cast(gpr_memrchr(host, '%', strlen(host))); + char* host_end = + static_cast(gpr_memrchr(host.get(), '%', strlen(host.get()))); if (host_end != nullptr) { - GPR_ASSERT(host_end >= host); + GPR_ASSERT(host_end >= host.get()); char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1]; - size_t host_without_scope_len = static_cast(host_end - host); + size_t host_without_scope_len = static_cast(host_end - host.get()); uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { if (log_errors) { @@ -154,7 +156,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - strncpy(host_without_scope, host, host_without_scope_len); + strncpy(host_without_scope, host.get(), host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { @@ -163,9 +165,9 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, } goto done; } - if (gpr_parse_bytes_to_uint32(host_end + 1, - strlen(host) - host_without_scope_len - 1, - &sin6_scope_id) == 0) { + if (gpr_parse_bytes_to_uint32( + host_end + 1, strlen(host.get()) - host_without_scope_len - 1, + &sin6_scope_id) == 0) { if ((sin6_scope_id = grpc_if_nametoindex(host_end + 1)) == 0) { gpr_log(GPR_ERROR, "Invalid interface name: '%s'. " @@ -177,8 +179,10 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; } else { - if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); + if (grpc_inet_pton(GRPC_AF_INET6, host.get(), &in6->sin6_addr) == 0) { + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host.get()); + } goto done; } } @@ -188,15 +192,14 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, goto done; } int port_num; - if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) { - if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port); + if (sscanf(port.get(), "%d", &port_num) != 1 || port_num < 0 || + port_num > 65535) { + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port.get()); goto done; } in6->sin6_port = grpc_htons(static_cast(port_num)); success = true; done: - gpr_free(host); - gpr_free(port); return success; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 32a339af359..ff15704d692 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -38,7 +38,6 @@ #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index ad0f1460121..0c1a8ba828f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -35,8 +35,8 @@ #include #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" @@ -355,9 +355,9 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; /* parse name, splitting it into host and port parts */ - char* host; - char* port; - gpr_split_host_port(name, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(name, &host, &port); if (host == nullptr) { error = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -370,7 +370,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto error_cleanup; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, query_timeout_ms, combiner, r); @@ -414,20 +414,22 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( } r->pending_queries = 1; if (grpc_ares_query_ipv6()) { - hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), - false /* is_balancer */); + hr = create_hostbyname_request_locked(r, host.get(), + grpc_strhtons(port.get()), + /*is_balancer=*/false); ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked, hr); } - hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), - false /* is_balancer */); + hr = + create_hostbyname_request_locked(r, host.get(), grpc_strhtons(port.get()), + /*is_balancer=*/false); ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked, hr); if (check_grpclb) { /* Query the SRV record */ grpc_ares_request_ref_locked(r); char* service_name; - gpr_asprintf(&service_name, "_grpclb._tcp.%s", host); + gpr_asprintf(&service_name, "_grpclb._tcp.%s", host.get()); ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_locked, r); gpr_free(service_name); @@ -435,28 +437,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( if (r->service_config_json_out != nullptr) { grpc_ares_request_ref_locked(r); char* config_name; - gpr_asprintf(&config_name, "_grpc_config.%s", host); + gpr_asprintf(&config_name, "_grpc_config.%s", host.get()); ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked, r); gpr_free(config_name); } grpc_ares_ev_driver_start_locked(r->ev_driver); grpc_ares_request_unref_locked(r); - gpr_free(host); - gpr_free(port); return; error_cleanup: GRPC_CLOSURE_SCHED(r->on_done, error); - gpr_free(host); - gpr_free(port); } static bool inner_resolve_as_ip_literal_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port, char** hostport) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* port, + grpc_core::UniquePtr* hostport) { + grpc_core::SplitHostPort(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s to host:port while attempting to resolve as ip " @@ -472,12 +471,14 @@ static bool inner_resolve_as_ip_literal_locked( name); return false; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } grpc_resolved_address addr; - GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port))); - if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || - grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { + GPR_ASSERT(grpc_core::JoinHostPort(hostport, host->get(), atoi(port->get()))); + if (grpc_parse_ipv4_hostport(hostport->get(), &addr, + false /* log errors */) || + grpc_parse_ipv6_hostport(hostport->get(), &addr, + false /* log errors */)) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */); @@ -489,24 +490,22 @@ static bool inner_resolve_as_ip_literal_locked( static bool resolve_as_ip_literal_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - char* hostport = nullptr; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::UniquePtr hostport; bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs, &host, &port, &hostport); - gpr_free(host); - gpr_free(port); - gpr_free(hostport); return out; } -static bool target_matches_localhost_inner(const char* name, char** host, - char** port) { - if (!gpr_split_host_port(name, host, port)) { +static bool target_matches_localhost_inner(const char* name, + grpc_core::UniquePtr* host, + grpc_core::UniquePtr* port) { + if (!grpc_core::SplitHostPort(name, host, port)) { gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name); return false; } - if (gpr_stricmp(*host, "localhost") == 0) { + if (gpr_stricmp(host->get(), "localhost") == 0) { return true; } else { return false; @@ -514,20 +513,17 @@ static bool target_matches_localhost_inner(const char* name, char** host, } static bool target_matches_localhost(const char* name) { - char* host = nullptr; - char* port = nullptr; - bool out = target_matches_localhost_inner(name, &host, &port); - gpr_free(host); - gpr_free(port); - return out; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + return target_matches_localhost_inner(name, &host, &port); } #ifdef GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY static bool inner_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); + grpc_core::UniquePtr* addrs, + grpc_core::UniquePtr* host, grpc_core::UniquePtr* port) { + grpc_core::SplitHostPort(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, "Failed to parse %s into host:port during manual localhost " @@ -543,12 +539,12 @@ static bool inner_maybe_resolve_localhost_manually_locked( name); return false; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } - if (gpr_stricmp(*host, "localhost") == 0) { + if (gpr_stricmp(host->get(), "localhost") == 0) { GPR_ASSERT(*addrs == nullptr); *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); + uint16_t numeric_port = grpc_strhtons(port->get()); // Append the ipv6 loopback address. struct sockaddr_in6 ipv6_loopback_addr; memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); @@ -576,13 +572,10 @@ static bool inner_maybe_resolve_localhost_manually_locked( static bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { - char* host = nullptr; - char* port = nullptr; - bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, - addrs, &host, &port); - gpr_free(host); - gpr_free(port); - return out; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + return inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); } #else /* GRPC_ARES_RESOLVE_LOCALHOST_MANUALLY */ static bool grpc_ares_maybe_resolve_localhost_manually_locked( diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index f85feb674dd..d9e3293deb6 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" bool grpc_ares_query_ipv6() { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 06cd5722ce3..1749cf77201 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 5ab75d02793..b8434a1cae4 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 7f613ee21bc..ff728a3dc43 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -32,7 +32,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/closure.h" diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 1465b0c644e..517b9297af4 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -30,7 +30,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/resolve_address.h" diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 8285ee76445..dc60ec2487b 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -37,7 +37,6 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resource_quota.h" diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 74c305b820f..c50d7e48d41 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -137,10 +137,10 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_STREAM_ID, static_cast(s->id)); gpr_free(msg); - p->error = - grpc_error_set_str(p->error, GRPC_ERROR_STR_RAW_BYTES, - grpc_dump_slice_to_slice( - *slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)); + p->error = grpc_error_set_str( + p->error, GRPC_ERROR_STR_RAW_BYTES, + grpc_slice_from_moved_string(grpc_core::UniquePtr( + grpc_dump_slice(*slice, GPR_DUMP_HEX | GPR_DUMP_ASCII)))); p->error = grpc_error_set_int(p->error, GRPC_ERROR_INT_OFFSET, cur - beg); p->state = GRPC_CHTTP2_DATA_ERROR; diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 3ddda268cfb..a5f6571c510 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -30,7 +30,6 @@ #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/cronet/transport/cronet_transport.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/endpoint.h" diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 4b130372e46..184ba17889d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -30,9 +30,9 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -406,14 +406,15 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, (strcmp(uri->scheme, "ipv6") == 0))) { const char* host_port = uri->path; if (*host_port == '/') ++host_port; - char* host = nullptr; - char* port = nullptr; - GPR_ASSERT(gpr_split_host_port(host_port, &host, &port)); + UniquePtr host; + UniquePtr port; + GPR_ASSERT(SplitHostPort(host_port, &host, &port)); int port_num = -1; if (port != nullptr) { - port_num = atoi(port); + port_num = atoi(port.get()); } - char* b64_host = grpc_base64_encode(host, strlen(host), false, false); + char* b64_host = + grpc_base64_encode(host.get(), strlen(host.get()), false, false); json_iterator = grpc_json_create_child(json_iterator, json, "tcpip_address", nullptr, GRPC_JSON_OBJECT, false); json = json_iterator; @@ -422,8 +423,6 @@ void PopulateSocketAddressJson(grpc_json* json, const char* name, "port", port_num); json_iterator = grpc_json_create_child(json_iterator, json, "ip_address", b64_host, GRPC_JSON_STRING, true); - gpr_free(host); - gpr_free(port); } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) { json_iterator = grpc_json_create_child(json_iterator, json, "uds_address", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/core/lib/gpr/host_port.cc b/src/core/lib/gpr/host_port.cc deleted file mode 100644 index a34e01cb516..00000000000 --- a/src/core/lib/gpr/host_port.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/gpr/host_port.h" - -#include - -#include -#include -#include - -#include "src/core/lib/gpr/string.h" - -int gpr_join_host_port(char** out, const char* host, int port) { - if (host[0] != '[' && strchr(host, ':') != nullptr) { - /* IPv6 literals must be enclosed in brackets. */ - return gpr_asprintf(out, "[%s]:%d", host, port); - } else { - /* Ordinary non-bracketed host:port. */ - return gpr_asprintf(out, "%s:%d", host, port); - } -} - -int gpr_split_host_port(const char* name, char** host, char** port) { - const char* host_start; - size_t host_len; - const char* port_start; - - *host = nullptr; - *port = nullptr; - - if (name[0] == '[') { - /* Parse a bracketed host, typically an IPv6 literal. */ - const char* rbracket = strchr(name, ']'); - if (rbracket == nullptr) { - /* Unmatched [ */ - return 0; - } - if (rbracket[1] == '\0') { - /* ] */ - port_start = nullptr; - } else if (rbracket[1] == ':') { - /* ]: */ - port_start = rbracket + 2; - } else { - /* ] */ - return 0; - } - host_start = name + 1; - host_len = static_cast(rbracket - host_start); - if (memchr(host_start, ':', host_len) == nullptr) { - /* Require all bracketed hosts to contain a colon, because a hostname or - IPv4 address should never use brackets. */ - return 0; - } - } else { - const char* colon = strchr(name, ':'); - if (colon != nullptr && strchr(colon + 1, ':') == nullptr) { - /* Exactly 1 colon. Split into host:port. */ - host_start = name; - host_len = static_cast(colon - name); - port_start = colon + 1; - } else { - /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ - host_start = name; - host_len = strlen(name); - port_start = nullptr; - } - } - - /* Allocate return values. */ - *host = static_cast(gpr_malloc(host_len + 1)); - memcpy(*host, host_start, host_len); - (*host)[host_len] = '\0'; - - if (port_start != nullptr) { - *port = gpr_strdup(port_start); - } - - return 1; -} diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index a39f56ef926..14436ec1bf9 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -289,17 +289,22 @@ 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 gpr_strincmp(const char* a, const char* b, size_t n) { int ca, cb; do { ca = tolower(*a); cb = tolower(*b); ++a; ++b; - } while (ca == cb && ca && cb); + --n; + } while (ca == cb && ca != 0 && cb != 0 && n != 0); return ca - cb; } +int gpr_stricmp(const char* a, const char* b) { + return gpr_strincmp(a, b, SIZE_MAX); +} + static void add_string_to_split(const char* beg, const char* end, char*** strs, size_t* nstrs, size_t* capstrs) { char* out = diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index bf59db7abfe..fcccf5e6764 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -115,6 +115,7 @@ 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); +int gpr_strincmp(const char* a, const char* b, size_t n); void* gpr_memrchr(const void* s, int c, size_t n); diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc new file mode 100644 index 00000000000..f3f8a73602a --- /dev/null +++ b/src/core/lib/gprpp/host_port.cc @@ -0,0 +1,97 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/host_port.h" + +#include + +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/string_view.h" + +namespace grpc_core { +int JoinHostPort(UniquePtr* out, const char* host, int port) { + char* tmp; + int ret; + if (host[0] != '[' && strchr(host, ':') != nullptr) { + /* IPv6 literals must be enclosed in brackets. */ + ret = gpr_asprintf(&tmp, "[%s]:%d", host, port); + } else { + /* Ordinary non-bracketed host:port. */ + ret = gpr_asprintf(&tmp, "%s:%d", host, port); + } + out->reset(tmp); + return ret; +} + +bool SplitHostPort(StringView name, StringView* host, StringView* port) { + if (name[0] == '[') { + /* Parse a bracketed host, typically an IPv6 literal. */ + const size_t rbracket = name.find(']', 1); + if (rbracket == grpc_core::StringView::npos) { + /* Unmatched [ */ + return false; + } + if (rbracket == name.size() - 1) { + /* ] */ + port->clear(); + } else if (name[rbracket + 1] == ':') { + /* ]: */ + *port = name.substr(rbracket + 2, name.size() - rbracket - 2); + } else { + /* ] */ + return false; + } + *host = name.substr(1, rbracket - 1); + if (host->find(':') == grpc_core::StringView::npos) { + /* Require all bracketed hosts to contain a colon, because a hostname or + IPv4 address should never use brackets. */ + host->clear(); + return false; + } + } else { + size_t colon = name.find(':'); + if (colon != grpc_core::StringView::npos && + name.find(':', colon + 1) == grpc_core::StringView::npos) { + /* Exactly 1 colon. Split into host:port. */ + *host = name.substr(0, colon); + *port = name.substr(colon + 1, name.size() - colon - 1); + } else { + /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ + *host = name; + port->clear(); + } + } + return true; +} + +bool SplitHostPort(StringView name, UniquePtr* host, + UniquePtr* port) { + StringView host_view; + StringView port_view; + const bool ret = SplitHostPort(name, &host_view, &port_view); + host->reset(host_view.empty() ? nullptr : host_view.dup().release()); + port->reset(port_view.empty() ? nullptr : port_view.dup().release()); + return ret; +} +} // namespace grpc_core diff --git a/src/core/lib/gpr/host_port.h b/src/core/lib/gprpp/host_port.h similarity index 51% rename from src/core/lib/gpr/host_port.h rename to src/core/lib/gprpp/host_port.h index 0bf0960f824..9a0b492b98f 100644 --- a/src/core/lib/gpr/host_port.h +++ b/src/core/lib/gprpp/host_port.h @@ -16,28 +16,44 @@ * */ -#ifndef GRPC_CORE_LIB_GPR_HOST_PORT_H -#define GRPC_CORE_LIB_GPR_HOST_PORT_H +#ifndef GRPC_CORE_LIB_GPRPP_HOST_PORT_H +#define GRPC_CORE_LIB_GPRPP_HOST_PORT_H #include +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/string_view.h" + +namespace grpc_core { + /** Given a host and port, creates a newly-allocated string of the form "host:port" or "[ho:st]:port", depending on whether the host contains colons like an IPv6 literal. If the host is already bracketed, then additional brackets will not be added. Usage is similar to gpr_asprintf: returns the number of bytes written - (excluding the final '\0'), and *out points to a string which must later be - destroyed using gpr_free(). + (excluding the final '\0'), and *out points to a string. In the unlikely event of an error, returns -1 and sets *out to NULL. */ -int gpr_join_host_port(char** out, const char* host, int port); +int JoinHostPort(UniquePtr* out, const char* host, int port); /** Given a name in the form "host:port" or "[ho:st]:port", split into hostname - and port number, into newly allocated strings, which must later be - destroyed using gpr_free(). - Return 1 on success, 0 on failure. Guarantees *host and *port == NULL on - failure. */ -int gpr_split_host_port(const char* name, char** host, char** port); + and port number. + + There are two variants of this method: + 1) StringView output: port and host are returned as views on name. + 2) char* output: port and host are copied into newly allocated strings. + + Prefer variant (1) over (2), because no allocation or copy is performed in + variant (1). Use (2) only when interacting with C API that mandate + null-terminated strings. + + Return true on success, false on failure. Guarantees *host and *port are + cleared on failure. */ +bool SplitHostPort(StringView name, StringView* host, StringView* port); +bool SplitHostPort(StringView name, UniquePtr* host, + UniquePtr* port); + +} // namespace grpc_core -#endif /* GRPC_CORE_LIB_GPR_HOST_PORT_H */ +#endif /* GRPC_CORE_LIB_GPRPP_HOST_PORT_H */ diff --git a/src/core/lib/gprpp/string_view.h b/src/core/lib/gprpp/string_view.h new file mode 100644 index 00000000000..05a81066d48 --- /dev/null +++ b/src/core/lib/gprpp/string_view.h @@ -0,0 +1,143 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef GRPC_CORE_LIB_GPRPP_STRING_VIEW_H +#define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { + +// Provides a light-weight view over a char array or a slice, similar but not +// identical to absl::string_view. +// +// Any method that has the same name as absl::string_view MUST HAVE identical +// semantics to what absl::string_view provides. +// +// Methods that are not part of absl::string_view API, must be clearly +// annotated. +// +// StringView does not own the buffers that back the view. Callers must ensure +// the buffer stays around while the StringView is accessible. +// +// Pass StringView by value in functions, since it is exactly two pointers in +// size. +// +// The interface used here is not identical to absl::string_view. Notably, we +// need to support slices while we cannot support std::string, and gpr string +// style functions such as strdup() and cmp(). Once we switch to +// absl::string_view this class will inherit from absl::string_view and add the +// gRPC-specific APIs. +class StringView final { + public: + static constexpr size_t npos = std::numeric_limits::max(); + + constexpr StringView(const char* ptr, size_t size) : ptr_(ptr), size_(size) {} + constexpr StringView(const char* ptr) + : StringView(ptr, ptr == nullptr ? 0 : strlen(ptr)) {} + // Not part of absl::string_view API. + StringView(const grpc_slice& slice) + : StringView(reinterpret_cast(GRPC_SLICE_START_PTR(slice)), + GRPC_SLICE_LENGTH(slice)) {} + constexpr StringView() : StringView(nullptr, 0) {} + + constexpr const char* data() const { return ptr_; } + constexpr size_t size() const { return size_; } + constexpr bool empty() const { return size_ == 0; } + + StringView substr(size_t start, size_t size = npos) { + GPR_DEBUG_ASSERT(start + size <= size_); + return StringView(ptr_ + start, std::min(size, size_ - start)); + } + + constexpr const char& operator[](size_t i) const { return ptr_[i]; } + + const char& front() const { return ptr_[0]; } + const char& back() const { return ptr_[size_ - 1]; } + + void remove_prefix(size_t n) { + GPR_DEBUG_ASSERT(n <= size_); + ptr_ += n; + size_ -= n; + } + + void remove_suffix(size_t n) { + GPR_DEBUG_ASSERT(n <= size_); + size_ -= n; + } + + size_t find(char c, size_t pos = 0) const { + if (empty() || pos >= size_) return npos; + const char* result = + static_cast(memchr(ptr_ + pos, c, size_ - pos)); + return result != nullptr ? result - ptr_ : npos; + } + + void clear() { + ptr_ = nullptr; + size_ = 0; + } + + // Creates a dup of the string viewed by this class. + // Return value is null-terminated and never nullptr. + // + // Not part of absl::string_view API. + grpc_core::UniquePtr dup() const { + char* str = static_cast(gpr_malloc(size_ + 1)); + if (size_ > 0) memcpy(str, ptr_, size_); + str[size_] = '\0'; + return grpc_core::UniquePtr(str); + } + + // Not part of absl::string_view API. + int cmp(StringView other) const { + const size_t len = GPR_MIN(size(), other.size()); + const int ret = strncmp(data(), other.data(), len); + if (ret != 0) return ret; + if (size() == other.size()) return 0; + if (size() < other.size()) return -1; + return 1; + } + + private: + const char* ptr_; + size_t size_; +}; + +inline bool operator==(StringView lhs, StringView rhs) { + return lhs.size() == rhs.size() && + strncmp(lhs.data(), rhs.data(), lhs.size()) == 0; +} + +inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); } + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 762cbe41bcf..8196019f098 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -108,7 +109,8 @@ class grpc_httpcli_ssl_channel_security_connector final return strcmp(secure_peer_name_, other->secure_peer_name_); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { *error = GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/resolve_address_custom.cc b/src/core/lib/iomgr/resolve_address_custom.cc index 9cf7817f66e..64c33cdc0d4 100644 --- a/src/core/lib/iomgr/resolve_address_custom.cc +++ b/src/core/lib/iomgr/resolve_address_custom.cc @@ -24,9 +24,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/resolve_address_custom.h" @@ -86,11 +86,12 @@ void grpc_custom_resolve_callback(grpc_custom_resolver* r, } static grpc_error* try_split_host_port(const char* name, - const char* default_port, char** host, - char** port) { + const char* default_port, + grpc_core::UniquePtr* host, + grpc_core::UniquePtr* port) { /* parse name, splitting it into host and port parts */ grpc_error* error; - gpr_split_host_port(name, host, port); + SplitHostPort(name, host, port); if (*host == nullptr) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -107,7 +108,7 @@ static grpc_error* try_split_host_port(const char* name, gpr_free(msg); return error; } - *port = gpr_strdup(default_port); + port->reset(gpr_strdup(default_port)); } return GRPC_ERROR_NONE; } @@ -115,28 +116,26 @@ static grpc_error* try_split_host_port(const char* name, static grpc_error* blocking_resolve_address_impl( const char* name, const char* default_port, grpc_resolved_addresses** addresses) { - char* host; - char* port; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { - gpr_free(host); - gpr_free(port); return err; } /* Call getaddrinfo */ grpc_custom_resolver resolver; - resolver.host = host; - resolver.port = port; + resolver.host = host.get(); + resolver.port = port.get(); grpc_resolved_addresses* addrs; grpc_core::ExecCtx* curr = grpc_core::ExecCtx::Get(); grpc_core::ExecCtx::Set(nullptr); - err = resolve_address_vtable->resolve(host, port, &addrs); + err = resolve_address_vtable->resolve(host.get(), port.get(), &addrs); if (err != GRPC_ERROR_NONE) { if (retry_named_port_failure(&resolver, &addrs)) { GRPC_ERROR_UNREF(err); @@ -147,8 +146,6 @@ static grpc_error* blocking_resolve_address_impl( if (err == GRPC_ERROR_NONE) { *addresses = addrs; } - gpr_free(resolver.host); - gpr_free(resolver.port); return err; } @@ -157,22 +154,20 @@ static void resolve_address_impl(const char* name, const char* default_port, grpc_closure* on_done, grpc_resolved_addresses** addrs) { grpc_custom_resolver* r = nullptr; - char* host = nullptr; - char* port = nullptr; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_error* err; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_done, err); - gpr_free(host); - gpr_free(port); return; } r = (grpc_custom_resolver*)gpr_malloc(sizeof(grpc_custom_resolver)); r->on_done = on_done; r->addresses = addrs; - r->host = host; - r->port = port; + r->host = host.release(); + r->port = port.release(); /* Call getaddrinfo */ resolve_address_vtable->resolve_async(r, r->host, r->port); diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index e6dd8f1ceab..e02dc19bb27 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -33,9 +33,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -48,8 +48,6 @@ static grpc_error* posix_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = nullptr, *resp; - char* host; - char* port; int s; size_t i; grpc_error* err; @@ -59,8 +57,10 @@ static grpc_error* posix_blocking_resolve_address( return grpc_resolve_unix_domain_address(name + 5, addresses); } + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); + grpc_core::SplitHostPort(name, &host, &port); if (host == nullptr) { err = grpc_error_set_str( GRPC_ERROR_CREATE_FROM_STATIC_STRING("unparseable host:port"), @@ -74,7 +74,7 @@ static grpc_error* posix_blocking_resolve_address( GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name)); goto done; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } /* Call getaddrinfo */ @@ -84,16 +84,16 @@ static grpc_error* posix_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); + s = getaddrinfo(host.get(), port.get(), &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { /* Retry if well-known service name is recognized */ const char* svc[][2] = {{"http", "80"}, {"https", "443"}}; for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) { - if (strcmp(port, svc[i][0]) == 0) { + if (strcmp(port.get(), svc[i][0]) == 0) { GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, svc[i][1], &hints, &result); + s = getaddrinfo(host.get(), svc[i][1], &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; break; } @@ -133,8 +133,6 @@ static grpc_error* posix_blocking_resolve_address( err = GRPC_ERROR_NONE; done: - gpr_free(host); - gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 64351c38a8f..a06d5cefbcb 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -35,8 +35,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/executor.h" @@ -57,14 +57,14 @@ static grpc_error* windows_blocking_resolve_address( grpc_core::ExecCtx exec_ctx; struct addrinfo hints; struct addrinfo *result = NULL, *resp; - char* host; - char* port; int s; size_t i; grpc_error* error = GRPC_ERROR_NONE; /* parse name, splitting it into host and port parts */ - gpr_split_host_port(name, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(name, &host, &port); if (host == NULL) { char* msg; gpr_asprintf(&msg, "unparseable host:port: '%s'", name); @@ -80,7 +80,7 @@ static grpc_error* windows_blocking_resolve_address( gpr_free(msg); goto done; } - port = gpr_strdup(default_port); + port.reset(gpr_strdup(default_port)); } /* Call getaddrinfo */ @@ -90,7 +90,7 @@ static grpc_error* windows_blocking_resolve_address( hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ GRPC_SCHEDULING_START_BLOCKING_REGION; - s = getaddrinfo(host, port, &hints, &result); + s = getaddrinfo(host.get(), port.get(), &hints, &result); GRPC_SCHEDULING_END_BLOCKING_REGION; if (s != 0) { error = GRPC_WSA_ERROR(WSAGetLastError(), "getaddrinfo"); @@ -122,8 +122,6 @@ static grpc_error* windows_blocking_resolve_address( } done: - gpr_free(host); - gpr_free(port); if (result) { freeaddrinfo(result); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 0839bdfef2d..baadf1da99e 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -28,8 +28,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" @@ -181,15 +181,17 @@ int grpc_sockaddr_to_string(char** out, } if (ip != nullptr && grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != nullptr) { + grpc_core::UniquePtr tmp_out; if (sin6_scope_id != 0) { char* host_with_scope; /* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */ gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id); - ret = gpr_join_host_port(out, host_with_scope, port); + ret = grpc_core::JoinHostPort(&tmp_out, host_with_scope, port); gpr_free(host_with_scope); } else { - ret = gpr_join_host_port(out, ntop_buf, port); + ret = grpc_core::JoinHostPort(&tmp_out, ntop_buf, port); } + *out = tmp_out.release(); } else { ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family); } diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 2101651b33f..47d9f51b095 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -46,7 +46,6 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index 4b21322d746..fcad5edd222 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -34,7 +34,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/cfstream_handle.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint_cfstream.h" @@ -143,12 +143,13 @@ static void OnOpen(void* arg, grpc_error* error) { static void ParseResolvedAddress(const grpc_resolved_address* addr, CFStringRef* host, int* port) { - char *host_port, *host_string, *port_string; + char* host_port; grpc_sockaddr_to_string(&host_port, addr, 1); - gpr_split_host_port(host_port, &host_string, &port_string); - *host = CFStringCreateWithCString(NULL, host_string, kCFStringEncodingUTF8); - gpr_free(host_string); - gpr_free(port_string); + grpc_core::UniquePtr host_string; + grpc_core::UniquePtr port_string; + grpc_core::SplitHostPort(host_port, &host_string, &port_string); + *host = + CFStringCreateWithCString(NULL, host_string.get(), kCFStringEncodingUTF8); gpr_free(host_port); *port = grpc_sockaddr_get_port(addr); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 38b1f856d52..79908601130 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -108,10 +108,11 @@ class grpc_alts_channel_security_connector final return strcmp(target_name_, other->target_name_); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host == nullptr || strcmp(host, target_name_) != 0) { + if (host.empty() || host != target_name_) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "ALTS call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index c55fd34d0e2..940c2ac5ee5 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -31,8 +31,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -102,39 +102,35 @@ class grpc_fake_channel_security_connector final tsi_create_fake_handshaker(/*is_client=*/true), this)); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(target_, &target_hostname, &target_ignored_port); + grpc_core::StringView authority_hostname; + grpc_core::StringView authority_ignored_port; + grpc_core::StringView target_hostname; + grpc_core::StringView target_ignored_port; + grpc_core::SplitHostPort(host, &authority_hostname, + &authority_ignored_port); + grpc_core::SplitHostPort(target_, &target_hostname, &target_ignored_port); if (target_name_override_ != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(target_name_override_, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { + grpc_core::StringView fake_security_target_name_override_hostname; + grpc_core::StringView fake_security_target_name_override_ignored_port; + grpc_core::SplitHostPort( + target_name_override_, &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (authority_hostname != fake_security_target_name_override_hostname) { gpr_log(GPR_ERROR, "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); + host.data(), + fake_security_target_name_override_hostname.data()); abort(); } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); + } else if (authority_hostname != target_hostname) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", host.data(), + target_); abort(); } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); return true; } diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index c1a101d4ab8..5b777009d34 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -156,10 +156,11 @@ class grpc_local_channel_security_connector final creds->connect_type()); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - if (host == nullptr || strcmp(host, target_name_) != 0) { + if (host.empty() || host != target_name_) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "local call host does not match target name"); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 47c0ad5aa3d..2c7c982e719 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index f71ee54402d..e5ced44638b 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -98,7 +98,7 @@ class grpc_channel_security_connector : public grpc_security_connector { /// Returns true if completed synchronously, in which case \a error will /// be set to indicate the result. Otherwise, \a on_call_host_checked /// will be invoked when complete. - virtual bool check_call_host(const char* host, + virtual bool check_call_host(grpc_core::StringView host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) GRPC_ABSTRACT; diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index f920dc6046d..97c04cafce4 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -28,8 +28,8 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/handshaker.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -75,15 +75,14 @@ class grpc_ssl_channel_security_connector final ? nullptr : gpr_strdup(overridden_target_name)), verify_options_(&config->verify_options) { - char* port; - gpr_split_host_port(target_name, &target_name_, &port); - gpr_free(port); + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(target_name, &host, &port); + target_name_ = host.dup(); } ~grpc_ssl_channel_security_connector() override { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); - if (target_name_ != nullptr) gpr_free(target_name_); - if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_); } grpc_security_status InitializeHandshakerFactory( @@ -123,8 +122,8 @@ class grpc_ssl_channel_security_connector final tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_ - : target_name_, + overridden_target_name_ != nullptr ? overridden_target_name_.get() + : target_name_.get(), &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -139,8 +138,8 @@ class grpc_ssl_channel_security_connector final grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_ - : target_name_; + ? overridden_target_name_.get() + : target_name_.get(); grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); if (error == GRPC_ERROR_NONE && verify_options_->verify_peer_callback != nullptr) { @@ -175,17 +174,18 @@ class grpc_ssl_channel_security_connector final reinterpret_cast(other_sc); int c = channel_security_connector_cmp(other); if (c != 0) return c; - c = strcmp(target_name_, other->target_name_); + c = strcmp(target_name_.get(), other->target_name_.get()); if (c != 0) return c; return (overridden_target_name_ == nullptr || other->overridden_target_name_ == nullptr) - ? GPR_ICMP(overridden_target_name_, - other->overridden_target_name_) - : strcmp(overridden_target_name_, - other->overridden_target_name_); + ? GPR_ICMP(overridden_target_name_.get(), + other->overridden_target_name_.get()) + : strcmp(overridden_target_name_.get(), + other->overridden_target_name_.get()); } - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { grpc_security_status status = GRPC_SECURITY_ERROR; @@ -194,7 +194,7 @@ class grpc_ssl_channel_security_connector final /* If the target name was overridden, then the original target_name was 'checked' transitively during the previous peer check at the end of the handshake. */ - if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { + if (overridden_target_name_ != nullptr && host == target_name_.get()) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -212,8 +212,8 @@ class grpc_ssl_channel_security_connector final private: tsi_ssl_client_handshaker_factory* client_handshaker_factory_; - char* target_name_; - char* overridden_target_name_; + grpc_core::UniquePtr target_name_; + grpc_core::UniquePtr overridden_target_name_; const verify_peer_options* verify_options_; }; diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index cb0d5437988..ebb4a3f9ee8 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -27,9 +27,9 @@ #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" @@ -136,12 +136,13 @@ grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { return GRPC_ERROR_NONE; } -grpc_error* grpc_ssl_check_peer_name(const char* peer_name, +grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, const tsi_peer* peer) { /* Check the peer name if specified. */ - if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + if (!peer_name.empty() && !grpc_ssl_host_matches_name(peer, peer_name)) { char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", + peer_name.data()); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return error; @@ -149,15 +150,16 @@ grpc_error* grpc_ssl_check_peer_name(const char* peer_name, return GRPC_ERROR_NONE; } -bool grpc_ssl_check_call_host(const char* host, const char* target_name, - const char* overridden_target_name, +bool grpc_ssl_check_call_host(grpc_core::StringView host, + grpc_core::StringView target_name, + grpc_core::StringView overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { grpc_security_status status = GRPC_SECURITY_ERROR; tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - if (overridden_target_name != nullptr && strcmp(host, target_name) == 0) { + if (!overridden_target_name.empty() && host == target_name) { status = GRPC_SECURITY_OK; } if (status != GRPC_SECURITY_OK) { @@ -179,35 +181,28 @@ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { return alpn_protocol_strings; } -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { - char* allocated_name = nullptr; - int r; - - char* ignored_port; - gpr_split_host_port(peer_name, &allocated_name, &ignored_port); - gpr_free(ignored_port); - peer_name = allocated_name; - if (!peer_name) return 0; +int grpc_ssl_host_matches_name(const tsi_peer* peer, + grpc_core::StringView peer_name) { + grpc_core::StringView allocated_name; + grpc_core::StringView ignored_port; + grpc_core::SplitHostPort(peer_name, &allocated_name, &ignored_port); + if (allocated_name.empty()) return 0; // IPv6 zone-id should not be included in comparisons. - char* const zone_id = strchr(allocated_name, '%'); - if (zone_id != nullptr) *zone_id = '\0'; - - r = tsi_ssl_peer_matches_name(peer, peer_name); - gpr_free(allocated_name); - return r; + const size_t zone_id = allocated_name.find('%'); + if (zone_id != grpc_core::StringView::npos) { + allocated_name.remove_suffix(allocated_name.size() - zone_id); + } + return tsi_ssl_peer_matches_name(peer, allocated_name); } -bool grpc_ssl_cmp_target_name(const char* target_name, - const char* other_target_name, - const char* overridden_target_name, - const char* other_overridden_target_name) { - int c = strcmp(target_name, other_target_name); +int grpc_ssl_cmp_target_name( + grpc_core::StringView target_name, grpc_core::StringView other_target_name, + grpc_core::StringView overridden_target_name, + grpc_core::StringView other_overridden_target_name) { + int c = target_name.cmp(other_target_name); if (c != 0) return c; - return (overridden_target_name == nullptr || - other_overridden_target_name == nullptr) - ? GPR_ICMP(overridden_target_name, other_overridden_target_name) - : strcmp(overridden_target_name, other_overridden_target_name); + return overridden_target_name.cmp(other_overridden_target_name); } grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 1765a344c2a..bf8c1de3aae 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -28,6 +28,7 @@ #include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/string_view.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/ssl_transport_security.h" @@ -46,16 +47,17 @@ GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_not_use_system_ssl_roots); grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer); /* Check peer name information returned from SSL handshakes. */ -grpc_error* grpc_ssl_check_peer_name(const char* peer_name, +grpc_error* grpc_ssl_check_peer_name(grpc_core::StringView peer_name, const tsi_peer* peer); /* Compare targer_name information extracted from SSL security connectors. */ -bool grpc_ssl_cmp_target_name(const char* target_name, - const char* other_target_name, - const char* overridden_target_name, - const char* other_overridden_target_name); +int grpc_ssl_cmp_target_name( + grpc_core::StringView target_name, grpc_core::StringView other_target_name, + grpc_core::StringView overridden_target_name, + grpc_core::StringView other_overridden_target_name); /* Check the host that will be set for a call is acceptable.*/ -bool grpc_ssl_check_call_host(const char* host, const char* target_name, - const char* overridden_target_name, +bool grpc_ssl_check_call_host(grpc_core::StringView host, + grpc_core::StringView target_name, + grpc_core::StringView overridden_target_name, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error); @@ -89,7 +91,8 @@ grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( tsi_peer grpc_shallow_peer_from_ssl_auth_context( const grpc_auth_context* auth_context); void grpc_shallow_peer_destruct(tsi_peer* peer); -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); +int grpc_ssl_host_matches_name(const tsi_peer* peer, + grpc_core::StringView peer_name); /* --- Default SSL Root Store. --- */ namespace grpc_core { diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc index ebf9c905079..5853de4fc13 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -28,7 +28,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/ssl/ssl_credentials.h" #include "src/core/lib/security/credentials/tls/spiffe_credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" @@ -105,18 +105,13 @@ SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( ? nullptr : gpr_strdup(overridden_target_name)) { check_arg_ = ServerAuthorizationCheckArgCreate(this); - char* port; - gpr_split_host_port(target_name, &target_name_, &port); - gpr_free(port); + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(target_name, &host, &port); + target_name_ = host.dup(); } SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { - if (target_name_ != nullptr) { - gpr_free(target_name_); - } - if (overridden_target_name_ != nullptr) { - gpr_free(overridden_target_name_); - } if (client_handshaker_factory_ != nullptr) { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); } @@ -130,8 +125,8 @@ void SpiffeChannelSecurityConnector::add_handshakers( tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( client_handshaker_factory_, - overridden_target_name_ != nullptr ? overridden_target_name_ - : target_name_, + overridden_target_name_ != nullptr ? overridden_target_name_.get() + : target_name_.get(), &tsi_hs); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", @@ -147,8 +142,8 @@ void SpiffeChannelSecurityConnector::check_peer( grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) { const char* target_name = overridden_target_name_ != nullptr - ? overridden_target_name_ - : target_name_; + ? overridden_target_name_.get() + : target_name_.get(); grpc_error* error = grpc_ssl_check_alpn(&peer); if (error != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(on_peer_checked, error); @@ -203,16 +198,17 @@ int SpiffeChannelSecurityConnector::cmp( if (c != 0) { return c; } - return grpc_ssl_cmp_target_name(target_name_, other->target_name_, - overridden_target_name_, - other->overridden_target_name_); + return grpc_ssl_cmp_target_name(target_name_.get(), other->target_name_.get(), + overridden_target_name_.get(), + other->overridden_target_name_.get()); } bool SpiffeChannelSecurityConnector::check_call_host( - const char* host, grpc_auth_context* auth_context, + grpc_core::StringView host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) { - return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, - auth_context, on_call_host_checked, error); + return grpc_ssl_check_call_host(host, target_name_.get(), + overridden_target_name_.get(), auth_context, + on_call_host_checked, error); } void SpiffeChannelSecurityConnector::cancel_check_call_host( diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h index 56972153e07..5ea00ee85b6 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -53,7 +53,8 @@ class SpiffeChannelSecurityConnector final int cmp(const grpc_security_connector* other_sc) const override; - bool check_call_host(const char* host, grpc_auth_context* auth_context, + bool check_call_host(grpc_core::StringView host, + grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override; @@ -83,8 +84,8 @@ class SpiffeChannelSecurityConnector final grpc_tls_server_authorization_check_arg* arg); grpc_closure* on_peer_checked_; - char* target_name_; - char* overridden_target_name_; + grpc_core::UniquePtr target_name_; + grpc_core::UniquePtr overridden_target_name_; tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; grpc_tls_server_authorization_check_arg* check_arg_; }; diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 1062fc2f4fa..33343d276eb 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -346,7 +346,7 @@ static void auth_start_transport_stream_op_batch( GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch, grpc_schedule_on_exec_ctx); - char* call_host = grpc_slice_to_c_string(calld->host); + grpc_core::StringView call_host(calld->host); grpc_error* error = GRPC_ERROR_NONE; if (chand->security_connector->check_call_host( call_host, chand->auth_context.get(), @@ -360,7 +360,6 @@ static void auth_start_transport_stream_op_batch( &calld->check_call_host_cancel_closure, cancel_check_call_host, elem, grpc_schedule_on_exec_ctx)); } - gpr_free(call_host); return; /* early exit */ } } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 1b7e58d3ce0..0d28303e7dd 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -30,7 +30,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 25ae2cee285..d3c8982c847 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -233,11 +233,10 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) { /* Returns 1 if name looks like an IP address, 0 otherwise. This is a very rough heuristic, and only handles IPv6 in hexadecimal form. */ -static int looks_like_ip_address(const char* name) { - size_t i; +static int looks_like_ip_address(grpc_core::StringView name) { size_t dot_count = 0; size_t num_size = 0; - for (i = 0; i < strlen(name); i++) { + for (size_t i = 0; i < name.size(); ++i) { if (name[i] == ':') { /* IPv6 Address in hexadecimal form, : is not allowed in DNS names. */ return 1; @@ -1506,52 +1505,46 @@ static void tsi_ssl_server_handshaker_factory_destroy( gpr_free(self); } -static int does_entry_match_name(const char* entry, size_t entry_length, - const char* name) { - const char* dot; - const char* name_subdomain = nullptr; - size_t name_length = strlen(name); - size_t name_subdomain_length; - if (entry_length == 0) return 0; +static int does_entry_match_name(grpc_core::StringView entry, + grpc_core::StringView name) { + if (entry.empty()) return 0; /* Take care of '.' terminations. */ - if (name[name_length - 1] == '.') { - name_length--; + if (name.back() == '.') { + name.remove_suffix(1); } - if (entry[entry_length - 1] == '.') { - entry_length--; - if (entry_length == 0) return 0; + if (entry.back() == '.') { + entry.remove_suffix(1); + if (entry.empty()) return 0; } - if ((name_length == entry_length) && - strncmp(name, entry, entry_length) == 0) { + if (name == entry) { return 1; /* Perfect match. */ } - if (entry[0] != '*') return 0; + if (entry.front() != '*') return 0; /* Wildchar subdomain matching. */ - if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ + if (entry.size() < 3 || entry[1] != '.') { /* At least *.x */ gpr_log(GPR_ERROR, "Invalid wildchar entry."); return 0; } - name_subdomain = strchr(name, '.'); - if (name_subdomain == nullptr) return 0; - name_subdomain_length = strlen(name_subdomain); - if (name_subdomain_length < 2) return 0; - name_subdomain++; /* Starts after the dot. */ - name_subdomain_length--; - entry += 2; /* Remove *. */ - entry_length -= 2; - dot = strchr(name_subdomain, '.'); - if ((dot == nullptr) || (dot == &name_subdomain[name_subdomain_length - 1])) { - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); + size_t name_subdomain_pos = name.find('.'); + if (name_subdomain_pos == grpc_core::StringView::npos) return 0; + if (name_subdomain_pos >= name.size() - 2) return 0; + grpc_core::StringView name_subdomain = + name.substr(name_subdomain_pos + 1); /* Starts after the dot. */ + entry.remove_prefix(2); /* Remove *. */ + size_t dot = name_subdomain.find('.'); + if (dot == grpc_core::StringView::npos || dot == name_subdomain.size() - 1) { + grpc_core::UniquePtr name_subdomain_cstr(name_subdomain.dup()); + gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", + name_subdomain_cstr.get()); return 0; } - if (name_subdomain[name_subdomain_length - 1] == '.') { - name_subdomain_length--; + if (name_subdomain.back() == '.') { + name_subdomain.remove_suffix(1); } - return ((entry_length > 0) && (name_subdomain_length == entry_length) && - strncmp(entry, name_subdomain, entry_length) == 0); + return !entry.empty() && name_subdomain == entry; } static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, @@ -1919,7 +1912,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options( /* --- tsi_ssl utils. --- */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { +int tsi_ssl_peer_matches_name(const tsi_peer* peer, + grpc_core::StringView name) { size_t i = 0; size_t san_count = 0; const tsi_peer_property* cn_property = nullptr; @@ -1933,13 +1927,10 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { san_count++; - if (!like_ip && does_entry_match_name(property->value.data, - property->value.length, name)) { + grpc_core::StringView entry(property->value.data, property->value.length); + if (!like_ip && does_entry_match_name(entry, name)) { return 1; - } else if (like_ip && - strncmp(name, property->value.data, property->value.length) == - 0 && - strlen(name) == property->value.length) { + } else if (like_ip && name == entry) { /* IP Addresses are exact matches only. */ return 1; } @@ -1951,8 +1942,9 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { /* If there's no SAN, try the CN, but only if its not like an IP Address */ if (san_count == 0 && cn_property != nullptr && !like_ip) { - if (does_entry_match_name(cn_property->value.data, - cn_property->value.length, name)) { + if (does_entry_match_name(grpc_core::StringView(cn_property->value.data, + cn_property->value.length), + name)) { return 1; } } diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 769949e4aad..0203141e56e 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/gprpp/string_view.h" #include "src/core/tsi/transport_security_interface.h" /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */ @@ -306,7 +307,7 @@ void tsi_ssl_server_handshaker_factory_unref( - handle mixed case. - handle %encoded chars. - handle public suffix wildchar more strictly (e.g. *.co.uk) */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name); +int tsi_ssl_peer_matches_name(const tsi_peer* peer, grpc_core::StringView name); /* --- Testing support. --- diff --git a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm index a24734024dc..ad426014a5b 100644 --- a/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CronetTests/CoreCronetEnd2EndTests.mm @@ -37,9 +37,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -51,19 +51,18 @@ #import "../ConfigureCronet.h" -typedef struct fullstack_secure_fixture_data { - char *localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_secure_fixture_data *ffd = - (fullstack_secure_fixture_data *)gpr_malloc(sizeof(fullstack_secure_fixture_data)); + fullstack_secure_fixture_data *ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "127.0.0.1", port); + grpc_core::JoinHostPort(&ffd->localaddr, "127.0.0.1", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(NULL); @@ -83,7 +82,8 @@ static void cronet_init_client_secure_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args, stream_engine *cronetEngine) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - f->client = grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL); + f->client = + grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr.get(), client_args, NULL); GPR_ASSERT(f->client != NULL); } @@ -96,15 +96,14 @@ static void chttp2_init_server_secure_fullstack(grpc_end2end_test_fixture *f, } f->server = grpc_server_create(server_args, NULL); grpc_server_register_completion_queue(f->server, f->cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); } static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { fullstack_secure_fixture_data *ffd = (fullstack_secure_fixture_data *)f->fixture_data; - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void cronet_init_client_simple_ssl_secure_fullstack(grpc_end2end_test_fixture *f, diff --git a/src/objective-c/tests/CronetTests/CronetUnitTests.mm b/src/objective-c/tests/CronetTests/CronetUnitTests.mm index 2473cf612be..4e2e70f1512 100644 --- a/src/objective-c/tests/CronetTests/CronetUnitTests.mm +++ b/src/objective-c/tests/CronetTests/CronetUnitTests.mm @@ -33,9 +33,9 @@ #import "src/core/lib/channel/channel_args.h" #import "src/core/lib/gpr/env.h" -#import "src/core/lib/gpr/host_port.h" #import "src/core/lib/gpr/string.h" #import "src/core/lib/gpr/tmpfile.h" +#import "src/core/lib/gprpp/host_port.h" #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" @@ -133,11 +133,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, NULL, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), NULL, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; @@ -264,11 +264,11 @@ unsigned int parse_h2_length(const char *field) { {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); - char *addr; - gpr_join_host_port(&addr, "127.0.0.1", port); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); grpc_completion_queue *cq = grpc_completion_queue_create_for_next(NULL); stream_engine *cronetEngine = [Cronet getGlobalEngine]; - grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr, args, NULL); + grpc_channel *client = grpc_cronet_secure_channel_create(cronetEngine, addr.get(), args, NULL); cq_verifier *cqv = cq_verifier_create(cq); grpc_op ops[6]; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2619ccf9740..c7caee551ce 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -27,7 +27,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gpr/env_linux.cc', 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc', - 'src/core/lib/gpr/host_port.cc', 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/log_android.cc', 'src/core/lib/gpr/log_linux.cc', @@ -54,6 +53,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', 'src/core/lib/gprpp/global_config_env.cc', + 'src/core/lib/gprpp/host_port.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/test/core/bad_ssl/bad_ssl_test.cc b/test/core/bad_ssl/bad_ssl_test.cc index 8dd55f64944..deae9072613 100644 --- a/test/core/bad_ssl/bad_ssl_test.cc +++ b/test/core/bad_ssl/bad_ssl_test.cc @@ -25,8 +25,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -144,7 +145,9 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/bad_ssl_%s_server%s", root, test, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); @@ -153,7 +156,6 @@ int main(int argc, char** argv) { run_test(args[2], i); grpc_shutdown(); } - gpr_free(args[2]); gpr_subprocess_interrupt(svr); status = gpr_subprocess_join(svr); diff --git a/test/core/client_channel/parse_address_with_named_scope_id_test.cc b/test/core/client_channel/parse_address_with_named_scope_id_test.cc index bfafa745178..071fb88b734 100644 --- a/test/core/client_channel/parse_address_with_named_scope_id_test.cc +++ b/test/core/client_channel/parse_address_with_named_scope_id_test.cc @@ -30,7 +30,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_utils.h" #include "test/core/util/test_config.h" @@ -60,20 +61,20 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo( struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { grpc_uri* uri = grpc_uri_parse(uri_text, 0); - char* host = nullptr; - char* port = nullptr; - gpr_split_host_port(uri->path, &host, &port); + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; + grpc_core::SplitHostPort(uri->path, &host, &port); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICHOST; struct addrinfo* result; - int res = getaddrinfo(host, port, &hints, &result); + int res = getaddrinfo(host.get(), port.get(), &hints, &result); if (res != 0) { gpr_log(GPR_ERROR, - "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", host, - port, res); + "getaddrinfo failed to resolve host:%s port:%s. Error: %d.", + host.get(), port.get(), res); abort(); } size_t num_addrs_from_getaddrinfo = 0; @@ -86,8 +87,6 @@ struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) { *reinterpret_cast(result->ai_addr); // Cleanup freeaddrinfo(result); - gpr_free(host); - gpr_free(port); grpc_uri_destroy(uri); return out; } diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 2d74b6b77b3..db480463b68 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -29,8 +29,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -71,7 +71,7 @@ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 struct rpc_state { - char* target; + grpc_core::UniquePtr target; grpc_completion_queue* cq; grpc_channel* channel; grpc_call* call; @@ -165,8 +165,9 @@ static void start_rpc(int target_port, grpc_status_code expected_status, state.cq = grpc_completion_queue_create_for_next(nullptr); cqv = cq_verifier_create(state.cq); - gpr_join_host_port(&state.target, "127.0.0.1", target_port); - state.channel = grpc_insecure_channel_create(state.target, nullptr, nullptr); + grpc_core::JoinHostPort(&state.target, "127.0.0.1", target_port); + state.channel = + grpc_insecure_channel_create(state.target.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("localhost"); state.call = grpc_channel_create_call( state.channel, nullptr, GRPC_PROPAGATE_DEFAULTS, state.cq, @@ -230,7 +231,7 @@ static void cleanup_rpc() { } while (ev.type != GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(state.cq); grpc_channel_destroy(state.channel); - gpr_free(state.target); + state.target.reset(); } typedef struct { diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 446e7b045a1..3bb6d2e23b6 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -24,7 +24,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" @@ -77,10 +77,10 @@ static void run_test(bool wait_for_ready, bool use_service_config) { /* create a call, channel to a port which will refuse connection */ int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, "127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr); - chan = grpc_insecure_channel_create(addr, args, nullptr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "127.0.0.1", port); + gpr_log(GPR_INFO, "server: %s", addr.get()); + chan = grpc_insecure_channel_create(addr.get(), args, nullptr); grpc_slice host = grpc_slice_from_static_string("nonexistant"); gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); call = @@ -88,8 +88,6 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_slice_from_static_string("/service/method"), &host, deadline, nullptr); - gpr_free(addr); - memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index 330af8fce07..cb49e0030b4 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -28,8 +28,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -70,8 +70,6 @@ static void log_resolved_addrs(const char* label, const char* hostname) { void test_connect(const char* server_host, const char* client_host, int port, int expect_ok) { - char* client_hostport; - char* server_hostport; grpc_channel* client; grpc_server* server; grpc_completion_queue* cq; @@ -99,7 +97,8 @@ void test_connect(const char* server_host, const char* client_host, int port, picked_port = 1; } - gpr_join_host_port(&server_hostport, server_host, port); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, server_host, port); grpc_metadata_array_init(&initial_metadata_recv); grpc_metadata_array_init(&trailing_metadata_recv); @@ -111,7 +110,7 @@ void test_connect(const char* server_host, const char* client_host, int port, server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(server, cq, nullptr); GPR_ASSERT((got_port = grpc_server_add_insecure_http2_port( - server, server_hostport)) > 0); + server, server_hostport.get())) > 0); if (port == 0) { port = got_port; } else { @@ -121,6 +120,7 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv = cq_verifier_create(cq); /* Create client. */ + grpc_core::UniquePtr client_hostport; if (client_host[0] == 'i') { /* for ipv4:/ipv6: addresses, concatenate the port to each of the parts */ size_t i; @@ -139,8 +139,8 @@ void test_connect(const char* server_host, const char* client_host, int port, gpr_asprintf(&hosts_with_port[i], "%s:%d", uri_part_str, port); gpr_free(uri_part_str); } - client_hostport = gpr_strjoin_sep((const char**)hosts_with_port, - uri_parts.count, ",", nullptr); + client_hostport.reset(gpr_strjoin_sep((const char**)hosts_with_port, + uri_parts.count, ",", nullptr)); for (i = 0; i < uri_parts.count; i++) { gpr_free(hosts_with_port[i]); } @@ -148,18 +148,17 @@ void test_connect(const char* server_host, const char* client_host, int port, grpc_slice_buffer_destroy(&uri_parts); grpc_slice_unref(uri_slice); } else { - gpr_join_host_port(&client_hostport, client_host, port); + grpc_core::JoinHostPort(&client_hostport, client_host, port); } - client = grpc_insecure_channel_create(client_hostport, nullptr, nullptr); + client = + grpc_insecure_channel_create(client_hostport.get(), nullptr, nullptr); gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport, client_hostport, expect_ok ? "success" : "failure"); + server_hostport.get(), client_hostport.get(), + expect_ok ? "success" : "failure"); log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); - gpr_free(client_hostport); - gpr_free(server_hostport); - if (expect_ok) { /* Normal deadline, shouldn't be reached. */ deadline = grpc_timeout_milliseconds_to_deadline(60000); diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc index 60442ddcc77..72cb96138e1 100644 --- a/test/core/end2end/fixtures/h2_census.cc +++ b/test/core/end2end/fixtures/h2_census.cc @@ -29,25 +29,23 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -71,7 +69,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, grpc_arg arg = make_census_enable_arg(); client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); { grpc_core::ExecCtx exec_ctx; @@ -94,15 +92,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, grpc_channel_args_destroy(server_args); } grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc index 01e5ae1b7b5..dd0c1fe0201 100644 --- a/test/core/end2end/fixtures/h2_compress.cc +++ b/test/core/end2end/fixtures/h2_compress.cc @@ -30,28 +30,29 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/compression/compression_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_compression_fixture_data { - char* localaddr; - grpc_channel_args* client_args_compression; - grpc_channel_args* server_args_compression; -} fullstack_compression_fixture_data; +struct fullstack_compression_fixture_data { + ~fullstack_compression_fixture_data() { + grpc_channel_args_destroy(client_args_compression); + grpc_channel_args_destroy(server_args_compression); + } + grpc_core::UniquePtr localaddr; + grpc_channel_args* client_args_compression = nullptr; + grpc_channel_args* server_args_compression = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_compression( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_compression_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_compression_fixture_data))); - memset(ffd, 0, sizeof(fullstack_compression_fixture_data)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::New(); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; @@ -73,7 +74,7 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture* f, grpc_channel_args_set_channel_default_compression_algorithm( client_args, GRPC_COMPRESS_GZIP); f->client = grpc_insecure_channel_create( - ffd->localaddr, ffd->client_args_compression, nullptr); + ffd->localaddr.get(), ffd->client_args_compression, nullptr); } void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, @@ -92,7 +93,8 @@ void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(ffd->server_args_compression, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } @@ -100,10 +102,7 @@ void chttp2_tear_down_fullstack_compression(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; fullstack_compression_fixture_data* ffd = static_cast(f->fixture_data); - grpc_channel_args_destroy(ffd->client_args_compression); - grpc_channel_args_destroy(ffd->server_args_compression); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc index ad83aab39f4..1375549ed6c 100644 --- a/test/core/end2end/fixtures/h2_fakesec.cc +++ b/test/core/end2end/fixtures/h2_fakesec.cc @@ -25,26 +25,24 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); - + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,8 +64,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -82,7 +80,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -91,8 +89,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_fake_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc index 6d559c4e516..ac4913674f0 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.cc +++ b/test/core/end2end/fixtures/h2_full+pipe.cc @@ -33,26 +33,25 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc index b8dbe261183..04de2a20182 100644 --- a/test/core/end2end/fixtures/h2_full+trace.cc +++ b/test/core/end2end/fixtures/h2_full+trace.cc @@ -34,25 +34,24 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -66,7 +65,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -79,15 +78,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc index cb0f7d275b3..8cfba4587e0 100644 --- a/test/core/end2end/fixtures/h2_full+workarounds.cc +++ b/test/core/end2end/fixtures/h2_full+workarounds.cc @@ -30,7 +30,7 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" @@ -39,24 +39,20 @@ static char* workarounds_arg[GRPC_MAX_WORKAROUND_ID] = { const_cast(GRPC_ARG_WORKAROUND_CRONET_COMPRESSION)}; -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -65,7 +61,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -88,7 +84,8 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args_new, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); grpc_channel_args_destroy(server_args_new); } @@ -96,8 +93,7 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc index c0d21288c7e..a3f2f25db5f 100644 --- a/test/core/end2end/fixtures/h2_full.cc +++ b/test/core/end2end/fixtures/h2_full.cc @@ -28,25 +28,24 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* localaddr; -} fullstack_fixture_data; +struct fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -60,7 +59,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, fullstack_fixture_data* ffd = static_cast(f->fixture_data); f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); + grpc_insecure_channel_create(ffd->localaddr.get(), client_args, nullptr); GPR_ASSERT(f->client); } @@ -73,15 +72,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->localaddr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc index 9b6a81494e1..18ba0e7f847 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.cc +++ b/test/core/end2end/fixtures/h2_http_proxy.cc @@ -30,26 +30,26 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_fixture_data { - char* server_addr; - grpc_end2end_http_proxy* proxy; -} fullstack_fixture_data; +struct fullstack_fixture_data { + ~fullstack_fixture_data() { grpc_end2end_http_proxy_destroy(proxy); } + grpc_core::UniquePtr server_addr; + grpc_end2end_http_proxy* proxy = nullptr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; memset(&f, 0, sizeof(f)); - fullstack_fixture_data* ffd = static_cast( - gpr_malloc(sizeof(fullstack_fixture_data))); + fullstack_fixture_data* ffd = grpc_core::New(); const int server_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&ffd->server_addr, "localhost", server_port); + grpc_core::JoinHostPort(&ffd->server_addr, "localhost", server_port); /* Passing client_args to proxy_create for the case of checking for proxy auth */ @@ -81,8 +81,8 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f, } gpr_setenv("http_proxy", proxy_uri); gpr_free(proxy_uri); - f->client = - grpc_insecure_channel_create(ffd->server_addr, client_args, nullptr); + f->client = grpc_insecure_channel_create(ffd->server_addr.get(), client_args, + nullptr); GPR_ASSERT(f->client); } @@ -95,16 +95,15 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f, } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr)); + GPR_ASSERT( + grpc_server_add_insecure_http2_port(f->server, ffd->server_addr.get())); grpc_server_start(f->server); } void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) { fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->server_addr); - grpc_end2end_http_proxy_destroy(ffd->proxy); - gpr_free(ffd); + grpc_core::Delete(ffd); } /* All test configurations */ diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc index f6996bf6be3..e27844be2df 100644 --- a/test/core/end2end/fixtures/h2_local_ipv4.cc +++ b/test/core/end2end/fixtures/h2_local_ipv4.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "127.0.0.1", port); diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc index e360727ca82..91acaa347f6 100644 --- a/test/core/end2end/fixtures/h2_local_ipv6.cc +++ b/test/core/end2end/fixtures/h2_local_ipv6.cc @@ -20,7 +20,7 @@ #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/end2end_tests.h" #include "test/core/end2end/fixtures/local_util.h" #include "test/core/util/port.h" @@ -31,7 +31,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6( grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); int port = grpc_pick_unused_port_or_die(); - gpr_join_host_port( + grpc_core::JoinHostPort( &static_cast(f.fixture_data) ->localaddr, "[::1]", port); diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc index f1bce213dc2..6c748896760 100644 --- a/test/core/end2end/fixtures/h2_local_uds.cc +++ b/test/core/end2end/fixtures/h2_local_uds.cc @@ -30,10 +30,10 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f = grpc_end2end_local_chttp2_create_fixture_fullstack(); - gpr_asprintf( - &static_cast(f.fixture_data) - ->localaddr, - "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + char* out = nullptr; + gpr_asprintf(&out, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++); + static_cast(f.fixture_data) + ->localaddr.reset(out); return f; } diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc index 113a6b11732..513fded4b62 100644 --- a/test/core/end2end/fixtures/h2_oauth2.cc +++ b/test/core/end2end/fixtures/h2_oauth2.cc @@ -25,7 +25,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -36,9 +36,9 @@ static const char oauth2_md[] = "Bearer aaslkfjs424535asdf"; static const char* client_identity_property_name = "smurf_name"; static const char* client_identity = "Brainy Smurf"; -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static const grpc_metadata* find_metadata(const grpc_metadata* md, size_t md_count, const char* key, @@ -95,16 +95,12 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - return f; } @@ -113,8 +109,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -129,7 +125,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -138,8 +134,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc index e334396ea7c..f0ada89d14d 100644 --- a/test/core/end2end/fixtures/h2_proxy.cc +++ b/test/core/end2end/fixtures/h2_proxy.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/fixtures/proxy.h" diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index cdf091bac10..4352ef640cd 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -28,9 +28,9 @@ #include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/security/credentials/credentials.h" @@ -42,10 +42,15 @@ typedef grpc_core::InlinedVector ThreadList; -typedef struct fullstack_secure_fixture_data { - char* localaddr; +struct fullstack_secure_fixture_data { + ~fullstack_secure_fixture_data() { + for (size_t ind = 0; ind < thd_list.size(); ind++) { + thd_list[ind].Join(); + } + } + grpc_core::UniquePtr localaddr; ThreadList thd_list; -} fullstack_secure_fixture_data; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { @@ -54,7 +59,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( fullstack_secure_fixture_data* ffd = grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); @@ -74,8 +79,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -90,7 +95,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -99,10 +104,6 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { - ffd->thd_list[ind].Join(); - } - gpr_free(ffd->localaddr); grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc index 3fc9bc7f329..cb55bb72061 100644 --- a/test/core/end2end/fixtures/h2_ssl.cc +++ b/test/core/end2end/fixtures/h2_ssl.cc @@ -25,29 +25,28 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -69,8 +68,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -85,7 +84,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -94,8 +93,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc index 1d54a431364..2a9591845b9 100644 --- a/test/core/end2end/fixtures/h2_ssl_cred_reload.cc +++ b/test/core/end2end/fixtures/h2_ssl_cred_reload.cc @@ -25,19 +25,19 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -typedef struct fullstack_secure_fixture_data { - char* localaddr; - bool server_credential_reloaded; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; + bool server_credential_reloaded = false; +}; static grpc_ssl_certificate_config_reload_status ssl_server_certificate_config_callback( @@ -64,10 +64,9 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -89,8 +88,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -106,7 +105,7 @@ static void chttp2_init_server_secure_fullstack( ffd->server_credential_reloaded = false; f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -115,8 +114,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static void chttp2_init_client_simple_ssl_secure_fullstack( diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc index d5f695b1575..b16ffa1b8b8 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.cc +++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc @@ -25,7 +25,6 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/credentials/credentials.h" diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc index f251bbd28c5..2b6c73d39c7 100644 --- a/test/core/end2end/fixtures/h2_uds.cc +++ b/test/core/end2end/fixtures/h2_uds.cc @@ -31,7 +31,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index 6b5513f160e..da2381aa0a0 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -31,8 +31,8 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/closure.h" @@ -53,8 +53,7 @@ struct grpc_end2end_http_proxy { grpc_end2end_http_proxy() - : proxy_name(nullptr), - server(nullptr), + : server(nullptr), channel_args(nullptr), mu(nullptr), pollset(nullptr), @@ -62,7 +61,7 @@ struct grpc_end2end_http_proxy { gpr_ref_init(&users, 1); combiner = grpc_combiner_create(); } - char* proxy_name; + grpc_core::UniquePtr proxy_name; grpc_core::Thread thd; grpc_tcp_server* server; grpc_channel_args* channel_args; @@ -532,8 +531,8 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_end2end_http_proxy* proxy = grpc_core::New(); // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); - gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name); + grpc_core::JoinHostPort(&proxy->proxy_name, "localhost", proxy_port); + gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.get()); // Create TCP server. proxy->channel_args = grpc_channel_args_copy(args); grpc_error* error = @@ -573,7 +572,6 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { proxy->thd.Join(); grpc_tcp_server_shutdown_listeners(proxy->server); grpc_tcp_server_unref(proxy->server); - gpr_free(proxy->proxy_name); grpc_channel_args_destroy(proxy->channel_args); grpc_pollset_shutdown(proxy->pollset, GRPC_CLOSURE_CREATE(destroy_pollset, proxy->pollset, @@ -584,5 +582,5 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { const char* grpc_end2end_http_proxy_get_proxy_name( grpc_end2end_http_proxy* proxy) { - return proxy->proxy_name; + return proxy->proxy_name.get(); } diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc index dadf3ef455d..70cc6b05479 100644 --- a/test/core/end2end/fixtures/inproc.cc +++ b/test/core/end2end/fixtures/inproc.cc @@ -28,7 +28,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/inproc/inproc_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/fixtures/local_util.cc b/test/core/end2end/fixtures/local_util.cc index 5f0b0300ac0..767f3a28ef8 100644 --- a/test/core/end2end/fixtures/local_util.cc +++ b/test/core/end2end/fixtures/local_util.cc @@ -27,7 +27,6 @@ #include "src/core/ext/filters/http/server/http_server_filter.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/surface/server.h" @@ -37,8 +36,7 @@ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() { grpc_end2end_test_fixture f; grpc_end2end_local_fullstack_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -52,8 +50,8 @@ void grpc_end2end_local_chttp2_init_client_fullstack( grpc_channel_credentials* creds = grpc_local_credentials_create(type); grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -99,8 +97,8 @@ void grpc_end2end_local_chttp2_init_server_fullstack( nullptr}; grpc_server_credentials_set_auth_metadata_processor(creds, processor); } - GPR_ASSERT( - grpc_server_add_secure_http2_port(f->server, ffd->localaddr, creds)); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), + creds)); grpc_server_credentials_release(creds); grpc_server_start(f->server); } @@ -109,6 +107,5 @@ void grpc_end2end_local_chttp2_tear_down_fullstack( grpc_end2end_test_fixture* f) { grpc_end2end_local_fullstack_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h index f133b4d977e..df204d2fab2 100644 --- a/test/core/end2end/fixtures/local_util.h +++ b/test/core/end2end/fixtures/local_util.h @@ -22,9 +22,9 @@ #include "src/core/lib/surface/channel.h" -typedef struct grpc_end2end_local_fullstack_fixture_data { - char* localaddr; -} grpc_end2end_local_fullstack_fixture_data; +struct grpc_end2end_local_fullstack_fixture_data { + grpc_core::UniquePtr localaddr; +}; /* Utility functions shared by h2_local tests. */ grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack(); diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index 869b6e846d3..4ae7450b0df 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,16 +24,15 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "test/core/util/port.h" struct grpc_end2end_proxy { grpc_end2end_proxy() - : proxy_port(nullptr), - server_port(nullptr), - cq(nullptr), + : cq(nullptr), server(nullptr), client(nullptr), shutdown(false), @@ -42,8 +41,8 @@ struct grpc_end2end_proxy { memset(&new_call_metadata, 0, sizeof(new_call_metadata)); } grpc_core::Thread thd; - char* proxy_port; - char* server_port; + grpc_core::UniquePtr proxy_port; + grpc_core::UniquePtr server_port; grpc_completion_queue* cq; grpc_server* server; grpc_channel* client; @@ -92,15 +91,15 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, grpc_end2end_proxy* proxy = grpc_core::New(); - gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); - gpr_join_host_port(&proxy->server_port, "localhost", server_port); + grpc_core::JoinHostPort(&proxy->proxy_port, "localhost", proxy_port); + grpc_core::JoinHostPort(&proxy->server_port, "localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port, - proxy->server_port); + gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.get(), + proxy->server_port.get()); proxy->cq = grpc_completion_queue_create_for_next(nullptr); - proxy->server = def->create_server(proxy->proxy_port, server_args); - proxy->client = def->create_client(proxy->server_port, client_args); + proxy->server = def->create_server(proxy->proxy_port.get(), server_args); + proxy->client = def->create_client(proxy->server_port.get(), client_args); grpc_server_register_completion_queue(proxy->server, proxy->cq, nullptr); grpc_server_start(proxy->server); @@ -131,8 +130,6 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_server_shutdown_and_notify(proxy->server, proxy->cq, new_closure(shutdown_complete, proxy)); proxy->thd.Join(); - gpr_free(proxy->proxy_port); - gpr_free(proxy->server_port); grpc_server_destroy(proxy->server); grpc_channel_destroy(proxy->client); grpc_completion_queue_destroy(proxy->cq); @@ -441,9 +438,9 @@ static void thread_main(void* arg) { } const char* grpc_end2end_proxy_get_client_target(grpc_end2end_proxy* proxy) { - return proxy->proxy_port; + return proxy->proxy_port.get(); } const char* grpc_end2end_proxy_get_server_port(grpc_end2end_proxy* proxy) { - return proxy->server_port; + return proxy->server_port.get(); } diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index e9285778a2d..34a9ef760b5 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -40,20 +40,19 @@ namespace grpc { namespace testing { -typedef struct fullstack_secure_fixture_data { - char* localaddr; -} fullstack_secure_fixture_data; +struct fullstack_secure_fixture_data { + grpc_core::UniquePtr localaddr; +}; static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); fullstack_secure_fixture_data* ffd = - static_cast( - gpr_malloc(sizeof(fullstack_secure_fixture_data))); + grpc_core::New(); memset(&f, 0, sizeof(f)); - gpr_join_host_port(&ffd->localaddr, "localhost", port); + grpc_core::JoinHostPort(&ffd->localaddr, "localhost", port); f.fixture_data = ffd; f.cq = grpc_completion_queue_create_for_next(nullptr); @@ -73,8 +72,8 @@ static void chttp2_init_client_secure_fullstack( grpc_channel_credentials* creds) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - f->client = - grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + f->client = grpc_secure_channel_create(creds, ffd->localaddr.get(), + client_args, nullptr); GPR_ASSERT(f->client != nullptr); grpc_channel_credentials_release(creds); } @@ -89,7 +88,7 @@ static void chttp2_init_server_secure_fullstack( } f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr.get(), server_creds)); grpc_server_credentials_release(server_creds); grpc_server_start(f->server); @@ -98,8 +97,7 @@ static void chttp2_init_server_secure_fullstack( void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { fullstack_secure_fixture_data* ffd = static_cast(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); + grpc_core::Delete(ffd); } static int fail_server_auth_check(grpc_channel_args* server_args) { diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc index b2d0a5e1133..6ffc138820e 100644 --- a/test/core/end2end/h2_ssl_session_reuse_test.cc +++ b/test/core/end2end/h2_ssl_session_reuse_test.cc @@ -25,9 +25,9 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/ssl_utils.h" #include "test/core/end2end/cq_verifier.h" @@ -215,19 +215,18 @@ void drain_cq(grpc_completion_queue* cq) { TEST(H2SessionReuseTest, SingleReuse) { int port = grpc_pick_unused_port_or_die(); - char* server_addr; - gpr_join_host_port(&server_addr, "localhost", port); + grpc_core::UniquePtr server_addr; + grpc_core::JoinHostPort(&server_addr, "localhost", port); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_ssl_session_cache* cache = grpc_ssl_session_cache_create_lru(16); - grpc_server* server = server_create(cq, server_addr); + grpc_server* server = server_create(cq, server_addr.get()); - do_round_trip(cq, server, server_addr, cache, false); - do_round_trip(cq, server, server_addr, cache, true); - do_round_trip(cq, server, server_addr, cache, true); + do_round_trip(cq, server, server_addr.get(), cache, false); + do_round_trip(cq, server, server_addr.get(), cache, true); + do_round_trip(cq, server, server_addr.get(), cache, true); - gpr_free(server_addr); grpc_ssl_session_cache_destroy(cache); GPR_ASSERT(grpc_completion_queue_next( diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index bd28d192984..5f920fad638 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -25,7 +25,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -54,7 +55,6 @@ static struct test_state g_state; static void prepare_test(int is_client) { int port = grpc_pick_unused_port_or_die(); - char* server_hostport; grpc_op* op; g_state.is_client = is_client; grpc_metadata_array_init(&g_state.initial_metadata_recv); @@ -77,14 +77,13 @@ static void prepare_test(int is_client) { } else { g_state.server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(g_state.server, g_state.cq, nullptr); - gpr_join_host_port(&server_hostport, "0.0.0.0", port); - grpc_server_add_insecure_http2_port(g_state.server, server_hostport); + grpc_core::UniquePtr server_hostport; + grpc_core::JoinHostPort(&server_hostport, "0.0.0.0", port); + grpc_server_add_insecure_http2_port(g_state.server, server_hostport.get()); grpc_server_start(g_state.server); - gpr_free(server_hostport); - gpr_join_host_port(&server_hostport, "localhost", port); + grpc_core::JoinHostPort(&server_hostport, "localhost", port); g_state.chan = - grpc_insecure_channel_create(server_hostport, nullptr, nullptr); - gpr_free(server_hostport); + grpc_insecure_channel_create(server_hostport.get(), nullptr, nullptr); grpc_slice host = grpc_slice_from_static_string("bar"); g_state.call = grpc_channel_create_call( g_state.chan, nullptr, GRPC_PROPAGATE_DEFAULTS, g_state.cq, diff --git a/test/core/fling/fling_stream_test.cc b/test/core/fling/fling_stream_test.cc index 32bc9896414..474b4fbbc3b 100644 --- a/test/core/fling/fling_stream_test.cc +++ b/test/core/fling/fling_stream_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +46,24 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-stream"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/fling_test.cc b/test/core/fling/fling_test.cc index 3587a4acaae..3667d48f010 100644 --- a/test/core/fling/fling_test.cc +++ b/test/core/fling/fling_test.cc @@ -22,8 +22,9 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,23 +47,24 @@ int main(int argc, const char** argv) { gpr_asprintf(&args[0], "%s/fling_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/fling_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--scenario=ping-pong-request"); args[4] = const_cast("--no-secure"); args[5] = nullptr; cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/fling/server.cc b/test/core/fling/server.cc index cf7e2465d9e..241ac71bc7d 100644 --- a/test/core/fling/server.cc +++ b/test/core/fling/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" @@ -172,7 +172,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_event ev; call_state* s; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -199,8 +199,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -220,8 +220,8 @@ int main(int argc, char** argv) { grpc_server_register_completion_queue(server, cq, nullptr); grpc_server_start(server); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); grpc_call_details_init(&call_details); diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD index 434d55e0451..c2b2576ff03 100644 --- a/test/core/gpr/BUILD +++ b/test/core/gpr/BUILD @@ -58,16 +58,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "host_port_test", - srcs = ["host_port_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "log_test", srcs = ["log_test.cc"], diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index cd3232addfd..5cee96a3ad2 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -64,6 +64,16 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "host_port_test", + srcs = ["host_port_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "grpc_core_map_test", srcs = ["map_test.cc"], @@ -156,6 +166,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "string_view_test", + srcs = ["string_view_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr_base", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "thd_test", srcs = ["thd_test.cc"], diff --git a/test/core/gpr/host_port_test.cc b/test/core/gprpp/host_port_test.cc similarity index 86% rename from test/core/gpr/host_port_test.cc rename to test/core/gprpp/host_port_test.cc index b01bbf4b695..3474e6dc494 100644 --- a/test/core/gpr/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -21,18 +21,17 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/test_config.h" static void join_host_port_expect(const char* host, int port, const char* expected) { - char* buf; + grpc_core::UniquePtr buf; int len; - len = gpr_join_host_port(&buf, host, port); + len = grpc_core::JoinHostPort(&buf, host, port); GPR_ASSERT(len >= 0); - GPR_ASSERT(strlen(expected) == (size_t)len); - GPR_ASSERT(strcmp(expected, buf) == 0); - gpr_free(buf); + GPR_ASSERT(strlen(expected) == static_cast(len)); + GPR_ASSERT(strcmp(expected, buf.get()) == 0); } static void test_join_host_port(void) { diff --git a/test/core/gprpp/string_view_test.cc b/test/core/gprpp/string_view_test.cc new file mode 100644 index 00000000000..1c8adb1db14 --- /dev/null +++ b/test/core/gprpp/string_view_test.cc @@ -0,0 +1,163 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/string_view.h" + +#include +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +TEST(StringViewTest, Empty) { + grpc_core::StringView empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(empty.size(), 0lu); + + grpc_core::StringView empty_buf(""); + EXPECT_TRUE(empty_buf.empty()); + EXPECT_EQ(empty_buf.size(), 0lu); + + grpc_core::StringView empty_trimmed("foo", 0); + EXPECT_TRUE(empty_trimmed.empty()); + EXPECT_EQ(empty_trimmed.size(), 0lu); + + grpc_core::StringView empty_slice(grpc_empty_slice()); + EXPECT_TRUE(empty_slice.empty()); + EXPECT_EQ(empty_slice.size(), 0lu); +} + +TEST(StringViewTest, Size) { + constexpr char kStr[] = "foo"; + grpc_core::StringView str1(kStr); + EXPECT_EQ(str1.size(), strlen(kStr)); + grpc_core::StringView str2(kStr, 2); + EXPECT_EQ(str2.size(), 2lu); +} + +TEST(StringViewTest, Data) { + constexpr char kStr[] = "foo-bar"; + grpc_core::StringView str(kStr); + EXPECT_EQ(str.size(), strlen(kStr)); + for (size_t i = 0; i < strlen(kStr); ++i) { + EXPECT_EQ(str[i], kStr[i]); + } +} + +TEST(StringViewTest, Slice) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Dup) { + constexpr char kStr[] = "foo"; + grpc_core::StringView slice(grpc_slice_from_static_string(kStr)); + grpc_core::UniquePtr dup = slice.dup(); + EXPECT_EQ(0, strcmp(kStr, dup.get())); + EXPECT_EQ(slice.size(), strlen(kStr)); +} + +TEST(StringViewTest, Eq) { + constexpr char kStr1[] = "foo"; + constexpr char kStr2[] = "bar"; + grpc_core::StringView str1(kStr1); + EXPECT_EQ(kStr1, str1); + EXPECT_EQ(str1, kStr1); + grpc_core::StringView slice1(grpc_slice_from_static_string(kStr1)); + EXPECT_EQ(slice1, str1); + EXPECT_EQ(str1, slice1); + EXPECT_NE(slice1, kStr2); + EXPECT_NE(kStr2, slice1); + grpc_core::StringView slice2(grpc_slice_from_static_string(kStr2)); + EXPECT_NE(slice2, str1); + EXPECT_NE(str1, slice2); +} + +TEST(StringViewTest, Cmp) { + constexpr char kStr1[] = "abc"; + constexpr char kStr2[] = "abd"; + constexpr char kStr3[] = "abcd"; + grpc_core::StringView str1(kStr1); + grpc_core::StringView str2(kStr2); + grpc_core::StringView str3(kStr3); + EXPECT_EQ(str1.cmp(str1), 0); + EXPECT_LT(str1.cmp(str2), 0); + EXPECT_LT(str1.cmp(str3), 0); + EXPECT_EQ(str2.cmp(str2), 0); + EXPECT_GT(str2.cmp(str1), 0); + EXPECT_GT(str2.cmp(str3), 0); + EXPECT_EQ(str3.cmp(str3), 0); + EXPECT_GT(str3.cmp(str1), 0); + EXPECT_LT(str3.cmp(str2), 0); +} + +TEST(StringViewTest, RemovePrefix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_prefix(1); + EXPECT_EQ("bcd", str); + str.remove_prefix(2); + EXPECT_EQ("d", str); + str.remove_prefix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, RemoveSuffix) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + str.remove_suffix(1); + EXPECT_EQ("abc", str); + str.remove_suffix(2); + EXPECT_EQ("a", str); + str.remove_suffix(1); + EXPECT_EQ("", str); +} + +TEST(StringViewTest, Substring) { + constexpr char kStr[] = "abcd"; + grpc_core::StringView str(kStr); + EXPECT_EQ("bcd", str.substr(1)); + EXPECT_EQ("bc", str.substr(1, 2)); +} + +TEST(StringViewTest, Find) { + // Passing StringView::npos directly to GTEST macros result in link errors. + // Store the value in a local variable and use it in the test. + const size_t npos = grpc_core::StringView::npos; + constexpr char kStr[] = "abacad"; + grpc_core::StringView str(kStr); + EXPECT_EQ(0ul, str.find('a')); + EXPECT_EQ(2ul, str.find('a', 1)); + EXPECT_EQ(4ul, str.find('a', 3)); + EXPECT_EQ(1ul, str.find('b')); + EXPECT_EQ(npos, str.find('b', 2)); + EXPECT_EQ(npos, str.find('z')); +} + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/memory_usage/memory_usage_test.cc b/test/core/memory_usage/memory_usage_test.cc index 5c35b4e1d36..5df8af5658b 100644 --- a/test/core/memory_usage/memory_usage_test.cc +++ b/test/core/memory_usage/memory_usage_test.cc @@ -22,8 +22,8 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/util/port.h" #include "test/core/util/subprocess.h" @@ -46,22 +46,23 @@ int main(int argc, char** argv) { gpr_asprintf(&args[0], "%s/memory_usage_server%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--bind"); - gpr_join_host_port(&args[2], "::", port); + grpc_core::UniquePtr joined; + grpc_core::JoinHostPort(&joined, "::", port); + args[2] = joined.get(); args[3] = const_cast("--no-secure"); svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* start the client */ gpr_asprintf(&args[0], "%s/memory_usage_client%s", root, gpr_subprocess_binary_extension()); args[1] = const_cast("--target"); - gpr_join_host_port(&args[2], "127.0.0.1", port); + grpc_core::JoinHostPort(&joined, "127.0.0.1", port); + args[2] = joined.get(); args[3] = const_cast("--warmup=1000"); args[4] = const_cast("--benchmark=9000"); cli = gpr_subprocess_create(5, (const char**)args); gpr_free(args[0]); - gpr_free(args[2]); /* wait for completion */ printf("waiting for client\n"); diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6fb14fa31a0..ecdf17925ec 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -33,7 +33,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -149,7 +149,7 @@ static void sigint_handler(int x) { _exit(0); } int main(int argc, char** argv) { grpc_memory_counters_init(); grpc_event ev; - char* addr_buf = nullptr; + grpc_core::UniquePtr addr_buf; gpr_cmdline* cl; grpc_completion_queue* shutdown_cq; int shutdown_started = 0; @@ -174,8 +174,8 @@ int main(int argc, char** argv) { gpr_cmdline_destroy(cl); if (addr == nullptr) { - gpr_join_host_port(&addr_buf, "::", grpc_pick_unused_port_or_die()); - addr = addr_buf; + grpc_core::JoinHostPort(&addr_buf, "::", grpc_pick_unused_port_or_die()); + addr = addr_buf.get(); } gpr_log(GPR_INFO, "creating server on: %s", addr); @@ -202,8 +202,8 @@ int main(int argc, char** argv) { struct grpc_memory_counters after_server_create = grpc_memory_counters_snapshot(); - gpr_free(addr_buf); - addr = addr_buf = nullptr; + addr = nullptr; + addr_buf.reset(); // initialize call instances for (int i = 0; i < static_cast(sizeof(calls) / sizeof(fling_call)); diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc index 454cbd5747e..2c9b0d9aaed 100644 --- a/test/core/surface/num_external_connectivity_watchers_test.cc +++ b/test/core/surface/num_external_connectivity_watchers_test.cc @@ -22,7 +22,8 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -66,13 +67,11 @@ static void channel_idle_poll_for_timeout(grpc_channel* channel, static void run_timeouts_test(const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then let it time out */ @@ -111,7 +110,6 @@ static void run_timeouts_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } /* An edge scenario; sets channel state to explicitly, and outside @@ -120,13 +118,11 @@ static void run_channel_shutdown_before_timeout_test( const test_fixture* fixture) { gpr_log(GPR_INFO, "TEST: %s", fixture->name); - char* addr; - + grpc_core::UniquePtr addr; grpc_init(); + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); - - grpc_channel* channel = fixture->create_channel(addr); + grpc_channel* channel = fixture->create_channel(addr.get()); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); /* start 1 watcher and then shut down the channel before the timer goes off */ @@ -154,7 +150,6 @@ static void run_channel_shutdown_before_timeout_test( grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static grpc_channel* insecure_test_create_channel(const char* addr) { diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc index 3f9a7baf98b..46c4a24f5ed 100644 --- a/test/core/surface/sequential_connectivity_test.cc +++ b/test/core/surface/sequential_connectivity_test.cc @@ -22,7 +22,7 @@ #include #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -56,11 +56,11 @@ static void run_test(const test_fixture* fixture) { grpc_init(); - char* addr; - gpr_join_host_port(&addr, "localhost", grpc_pick_unused_port_or_die()); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, "localhost", grpc_pick_unused_port_or_die()); grpc_server* server = grpc_server_create(nullptr, nullptr); - fixture->add_server_port(server, addr); + fixture->add_server_port(server, addr.get()); grpc_completion_queue* server_cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, server_cq, nullptr); @@ -73,7 +73,7 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_channel* channels[NUM_CONNECTIONS]; for (size_t i = 0; i < NUM_CONNECTIONS; i++) { - channels[i] = fixture->create_channel(addr); + channels[i] = fixture->create_channel(addr.get()); gpr_timespec connect_deadline = grpc_timeout_seconds_to_deadline(30); grpc_connectivity_state state; @@ -116,7 +116,6 @@ static void run_test(const test_fixture* fixture) { grpc_completion_queue_destroy(cq); grpc_shutdown(); - gpr_free(addr); } static void insecure_test_add_port(grpc_server* server, const char* addr) { diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc index ffb7f14f987..a88362e13b0 100644 --- a/test/core/surface/server_chttp2_test.cc +++ b/test/core/surface/server_chttp2_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/tsi/fake_transport_security.h" @@ -47,17 +47,17 @@ void test_add_same_port_twice() { grpc_channel_args args = {1, &a}; int port = grpc_pick_unused_port_or_die(); - char* addr = nullptr; + grpc_core::UniquePtr addr; grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server* server = grpc_server_create(&args, nullptr); grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - gpr_join_host_port(&addr, "localhost", port); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds) == 0); + grpc_core::JoinHostPort(&addr, "localhost", port); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds) == 0); grpc_server_credentials_release(fake_creds); - gpr_free(addr); grpc_server_shutdown_and_notify(server, cq, nullptr); grpc_completion_queue_pluck(cq, nullptr, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc index 2fc166546b0..185a6757743 100644 --- a/test/core/surface/server_test.cc +++ b/test/core/surface/server_test.cc @@ -22,7 +22,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "test/core/util/port.h" @@ -106,18 +106,19 @@ void test_bind_server_twice(void) { void test_bind_server_to_addr(const char* host, bool secure) { int port = grpc_pick_unused_port_or_die(); - char* addr; - gpr_join_host_port(&addr, host, port); - gpr_log(GPR_INFO, "Test bind to %s", addr); + grpc_core::UniquePtr addr; + grpc_core::JoinHostPort(&addr, host, port); + gpr_log(GPR_INFO, "Test bind to %s", addr.get()); grpc_server* server = grpc_server_create(nullptr, nullptr); if (secure) { grpc_server_credentials* fake_creds = grpc_fake_transport_security_server_credentials_create(); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, fake_creds)); + GPR_ASSERT( + grpc_server_add_secure_http2_port(server, addr.get(), fake_creds)); grpc_server_credentials_release(fake_creds); } else { - GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr)); + GPR_ASSERT(grpc_server_add_insecure_http2_port(server, addr.get())); } grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); grpc_server_register_completion_queue(server, cq, nullptr); @@ -126,7 +127,6 @@ void test_bind_server_to_addr(const char* host, bool secure) { grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_MONOTONIC), nullptr); grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - gpr_free(addr); } static int external_dns_works(const char* host) { diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index 144ad64f095..03c088db772 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -25,7 +25,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 170584df2b9..d7803e53555 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -28,7 +28,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" diff --git a/test/cpp/interop/interop_test.cc b/test/cpp/interop/interop_test.cc index 8e45b877212..e0bacb3cfd6 100644 --- a/test/cpp/interop/interop_test.cc +++ b/test/cpp/interop/interop_test.cc @@ -32,7 +32,6 @@ #include "test/core/util/port.h" #include "test/cpp/util/test_config.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_utils_posix.h" diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index affc75bc634..a3d9936606d 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -40,8 +40,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" @@ -64,30 +64,28 @@ struct TestAddress { }; grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) { - char* host; - char* port; + grpc_core::UniquePtr host; + grpc_core::UniquePtr port; grpc_resolved_address resolved_addr; - gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port); + grpc_core::SplitHostPort(test_addr.dest_addr.c_str(), &host, &port); if (test_addr.family == AF_INET) { sockaddr_in in_dest; memset(&in_dest, 0, sizeof(sockaddr_in)); - in_dest.sin_port = htons(atoi(port)); + in_dest.sin_port = htons(atoi(port.get())); in_dest.sin_family = AF_INET; - GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET, host.get(), &in_dest.sin_addr) == 1); memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in)); resolved_addr.len = sizeof(sockaddr_in); } else { GPR_ASSERT(test_addr.family == AF_INET6); sockaddr_in6 in6_dest; memset(&in6_dest, 0, sizeof(sockaddr_in6)); - in6_dest.sin6_port = htons(atoi(port)); + in6_dest.sin6_port = htons(atoi(port.get())); in6_dest.sin6_family = AF_INET6; - GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1); + GPR_ASSERT(inet_pton(AF_INET6, host.get(), &in6_dest.sin6_addr) == 1); memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6)); resolved_addr.len = sizeof(sockaddr_in6); } - gpr_free(host); - gpr_free(port); return resolved_addr; } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 667011ae291..2d1a13d25a6 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/stats.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/thd.h" diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 6cea8143907..67ed307d2d7 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -46,8 +46,8 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/executor.h" @@ -506,10 +506,10 @@ int g_fake_non_responsive_dns_server_port = -1; void InjectBrokenNameServerList(ares_channel channel) { struct ares_addr_port_node dns_server_addrs[2]; memset(dns_server_addrs, 0, sizeof(dns_server_addrs)); - char* unused_host; - char* local_dns_server_port; - GPR_ASSERT(gpr_split_host_port(FLAGS_local_dns_server_address.c_str(), - &unused_host, &local_dns_server_port)); + grpc_core::UniquePtr unused_host; + grpc_core::UniquePtr local_dns_server_port; + GPR_ASSERT(grpc_core::SplitHostPort(FLAGS_local_dns_server_address.c_str(), + &unused_host, &local_dns_server_port)); gpr_log(GPR_DEBUG, "Injecting broken nameserver list. Bad server address:|[::1]:%d|. " "Good server address:%s", @@ -528,12 +528,10 @@ void InjectBrokenNameServerList(ares_channel channel) { dns_server_addrs[1].family = AF_INET; ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f; ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1; - dns_server_addrs[1].tcp_port = atoi(local_dns_server_port); - dns_server_addrs[1].udp_port = atoi(local_dns_server_port); + dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.get()); + dns_server_addrs[1].udp_port = atoi(local_dns_server_port.get()); dns_server_addrs[1].next = nullptr; GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS); - gpr_free(local_dns_server_port); - gpr_free(unused_host); } void StartResolvingLocked(void* arg, grpc_error* unused) { diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 668d9abf5ca..5fc14ddbabd 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -33,7 +33,6 @@ #include #include -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/client.h" diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 7d4d5d99446..cfc3c8e9a06 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -31,7 +31,7 @@ #include #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/port.h" @@ -52,15 +52,10 @@ using std::vector; namespace grpc { namespace testing { static std::string get_host(const std::string& worker) { - char* host; - char* port; - - gpr_split_host_port(worker.c_str(), &host, &port); - const string s(host); - - gpr_free(host); - gpr_free(port); - return s; + grpc_core::StringView host; + grpc_core::StringView port; + grpc_core::SplitHostPort(worker.c_str(), &host, &port); + return std::string(host.data(), host.size()); } static deque get_workers(const string& env_name) { @@ -324,11 +319,10 @@ std::unique_ptr RunScenario( client_config.add_server_targets(cli_target); } else { std::string host; - char* cli_target; + grpc_core::UniquePtr cli_target; host = get_host(workers[i]); - gpr_join_host_port(&cli_target, host.c_str(), init_status.port()); - client_config.add_server_targets(cli_target); - gpr_free(cli_target); + grpc_core::JoinHostPort(&cli_target, host.c_str(), init_status.port()); + client_config.add_server_targets(cli_target.get()); } } diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index 23fe72316a1..bdf94d86c10 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/worker_service.grpc.pb.h" #include "test/core/util/grpc_profiler.h" #include "test/core/util/histogram.h" @@ -279,12 +279,11 @@ QpsWorker::QpsWorker(int driver_port, int server_port, std::unique_ptr builder = CreateQpsServerBuilder(); if (driver_port >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", driver_port); + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", driver_port); builder->AddListeningPort( - server_address, + server_address.get(), GetCredentialsProvider()->GetServerCredentials(credential_type)); - gpr_free(server_address); } builder->RegisterService(impl_.get()); diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a5f8347c269..e9978212f95 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -34,7 +34,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/surface/completion_queue.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/core/util/test_config.h" @@ -80,11 +80,10 @@ class AsyncQpsServerTest final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } register_service(builder.get(), &async_service_); diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc index 4a346dd0178..1829905cb49 100644 --- a/test/cpp/qps/server_callback.cc +++ b/test/cpp/qps/server_callback.cc @@ -21,7 +21,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -103,11 +103,10 @@ class CallbackServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 2e63f5ec867..7b76e9c206a 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -25,7 +25,7 @@ #include #include -#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/proto/grpc/testing/benchmark_service.grpc.pb.h" #include "test/cpp/qps/qps_server_builder.h" #include "test/cpp/qps/server.h" @@ -160,11 +160,10 @@ class SynchronousServer final : public grpc::testing::Server { auto port_num = port(); // Negative port number means inproc server, so no listen port needed if (port_num >= 0) { - char* server_address = nullptr; - gpr_join_host_port(&server_address, "::", port_num); - builder->AddListeningPort(server_address, + grpc_core::UniquePtr server_address; + grpc_core::JoinHostPort(&server_address, "::", port_num); + builder->AddListeningPort(server_address.get(), Server::CreateServerCredentials(config)); - gpr_free(server_address); } ApplyConfigToBuilder(config, builder.get()); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index f1dd2e54e1d..69ff7eb6098 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1077,7 +1077,6 @@ src/core/lib/debug/trace.h \ src/core/lib/gpr/alloc.h \ src/core/lib/gpr/arena.h \ src/core/lib/gpr/env.h \ -src/core/lib/gpr/host_port.h \ src/core/lib/gpr/mpscq.h \ src/core/lib/gpr/murmur_hash.h \ src/core/lib/gpr/spinlock.h \ @@ -1099,6 +1098,7 @@ src/core/lib/gprpp/global_config.h \ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ +src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1108,6 +1108,7 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/http/format_request.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7768bca30f5..1dae91d2eaf 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1125,8 +1125,6 @@ src/core/lib/gpr/env.h \ src/core/lib/gpr/env_linux.cc \ src/core/lib/gpr/env_posix.cc \ src/core/lib/gpr/env_windows.cc \ -src/core/lib/gpr/host_port.cc \ -src/core/lib/gpr/host_port.h \ src/core/lib/gpr/log.cc \ src/core/lib/gpr/log_android.cc \ src/core/lib/gpr/log_linux.cc \ @@ -1175,6 +1173,8 @@ src/core/lib/gprpp/global_config_custom.h \ src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/global_config_env.h \ src/core/lib/gprpp/global_config_generic.h \ +src/core/lib/gprpp/host_port.cc \ +src/core/lib/gprpp/host_port.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ @@ -1184,6 +1184,7 @@ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/pair.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ +src/core/lib/gprpp/string_view.h \ src/core/lib/gprpp/sync.h \ src/core/lib/gprpp/thd.h \ src/core/lib/gprpp/thd_posix.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b157439a3f4..6b746decca9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -683,7 +683,7 @@ "language": "c", "name": "gpr_host_port_test", "src": [ - "test/core/gpr/host_port_test.cc" + "test/core/gprpp/host_port_test.cc" ], "third_party": false, "type": "target" @@ -5058,6 +5058,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "string_view_test", + "src": [ + "test/core/gprpp/string_view_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8189,7 +8207,6 @@ "src/core/lib/gpr/env_linux.cc", "src/core/lib/gpr/env_posix.cc", "src/core/lib/gpr/env_windows.cc", - "src/core/lib/gpr/host_port.cc", "src/core/lib/gpr/log.cc", "src/core/lib/gpr/log_android.cc", "src/core/lib/gpr/log_linux.cc", @@ -8216,6 +8233,7 @@ "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/host_port.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -8249,7 +8267,6 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8270,6 +8287,7 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8302,7 +8320,6 @@ "src/core/lib/gpr/alloc.h", "src/core/lib/gpr/arena.h", "src/core/lib/gpr/env.h", - "src/core/lib/gpr/host_port.h", "src/core/lib/gpr/mpscq.h", "src/core/lib/gpr/murmur_hash.h", "src/core/lib/gpr/spinlock.h", @@ -8323,6 +8340,7 @@ "src/core/lib/gprpp/global_config_custom.h", "src/core/lib/gprpp/global_config_env.h", "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/host_port.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8623,6 +8641,7 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", @@ -8780,6 +8799,7 @@ "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/string_view.h", "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 625d3bd295f..9e835c22bb6 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5730,6 +5730,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "string_view_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From c9ec1a64edd64b9a56b991d1d43544c0829fe746 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Jun 2019 11:20:30 -0400 Subject: [PATCH 506/676] Fix SplitHostPort for empty strings. Add unittests to catch such errors in the future. --- src/core/lib/gprpp/host_port.cc | 8 +++++-- test/core/gprpp/host_port_test.cc | 36 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index f3f8a73602a..82a3ab1add0 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -87,11 +87,15 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { bool SplitHostPort(StringView name, UniquePtr* host, UniquePtr* port) { + GPR_DEBUG_ASSERT(host != nullptr && *host == nullptr); + GPR_DEBUG_ASSERT(port != nullptr && *port == nullptr); StringView host_view; StringView port_view; const bool ret = SplitHostPort(name, &host_view, &port_view); - host->reset(host_view.empty() ? nullptr : host_view.dup().release()); - port->reset(port_view.empty() ? nullptr : port_view.dup().release()); + if (ret) { + *host = host_view.dup(); + *port = port_view.dup(); + } return ret; } } // namespace grpc_core diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc index 3474e6dc494..33ea4781491 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -48,11 +48,47 @@ static void test_join_host_port_garbage(void) { join_host_port_expect("::]", 107, "[::]]:107"); } +static void split_host_port_expect(const char* name, const char* host, + const char* port, bool ret) { + grpc_core::UniquePtr actual_host; + grpc_core::UniquePtr actual_port; + const bool actual_ret = + grpc_core::SplitHostPort(name, &actual_host, &actual_port); + GPR_ASSERT(actual_ret == ret); + if (host == nullptr) { + GPR_ASSERT(actual_host == nullptr); + } else { + GPR_ASSERT(strcmp(host, actual_host.get()) == 0); + } + if (port == nullptr) { + GPR_ASSERT(actual_port == nullptr); + } else { + GPR_ASSERT(strcmp(port, actual_port.get()) == 0); + } +} + +static void test_split_host_port() { + split_host_port_expect("", "", "", true); + split_host_port_expect("[a:b]", "a:b", "", true); + split_host_port_expect("1.2.3.4", "1.2.3.4", "", true); + split_host_port_expect("a:b:c::", "a:b:c::", "", true); + split_host_port_expect("[a:b]:30", "a:b", "30", true); + split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); + split_host_port_expect(":30", "", "30", true); +} + +static void test_split_host_port_invalid() { + split_host_port_expect("[a:b", nullptr, nullptr, false); + split_host_port_expect("[a:b]30", nullptr, nullptr, false); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); test_join_host_port(); test_join_host_port_garbage(); + test_split_host_port(); + test_split_host_port_invalid(); return 0; } From fedf7e373e172b07c32dcb303a628c0a572c8dd7 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Jun 2019 12:36:21 -0400 Subject: [PATCH 507/676] Fix a backward compatibility bug. To remain backward compatible, we only set port if it's a non-emptry string. But, we always store host. --- src/core/lib/gprpp/host_port.cc | 6 +++++- test/core/gprpp/host_port_test.cc | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index 82a3ab1add0..13b63eb902b 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -93,8 +93,12 @@ bool SplitHostPort(StringView name, UniquePtr* host, StringView port_view; const bool ret = SplitHostPort(name, &host_view, &port_view); if (ret) { + // We always set the host, but port is set only when it's non-empty, + // to remain backward compatible with the old split_host_port API. *host = host_view.dup(); - *port = port_view.dup(); + if (!port_view.empty()) { + *port = port_view.dup(); + } } return ret; } diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc index 33ea4781491..3b392da66e8 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -68,10 +68,10 @@ static void split_host_port_expect(const char* name, const char* host, } static void test_split_host_port() { - split_host_port_expect("", "", "", true); - split_host_port_expect("[a:b]", "a:b", "", true); - split_host_port_expect("1.2.3.4", "1.2.3.4", "", true); - split_host_port_expect("a:b:c::", "a:b:c::", "", true); + split_host_port_expect("", "", nullptr, true); + split_host_port_expect("[a:b]", "a:b", nullptr, true); + split_host_port_expect("1.2.3.4", "1.2.3.4", nullptr, true); + split_host_port_expect("a:b:c::", "a:b:c::", nullptr, true); split_host_port_expect("[a:b]:30", "a:b", "30", true); split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); split_host_port_expect(":30", "", "30", true); From ea63c00d38b144f8d488165021e328c27db8ffa5 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Jun 2019 17:40:12 -0400 Subject: [PATCH 508/676] Revert "Fix build failure in credential_test.cc" This reverts commit dc858eea2578f856394f9fd2cd7f4ef2725266d9. --- test/core/security/credentials_test.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 50340311fba..cbce595c354 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -32,9 +32,9 @@ #include #include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/host_port.h" #include "src/core/lib/http/httpcli.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/security/credentials/composite/composite_credentials.h" @@ -745,11 +745,11 @@ static void test_valid_sts_creds_options(void) { grpc_core::ValidateStsCredentialsOptions(&valid_options, &sts_url); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(sts_url != nullptr); - char* host; - char* port; - GPR_ASSERT(gpr_split_host_port(sts_url->authority, &host, &port)); - GPR_ASSERT(strcmp(host, "foo.com") == 0); - GPR_ASSERT(strcmp(port, "5555") == 0); + grpc_core::StringView host; + grpc_core::StringView port; + GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority, &host, &port)); + GPR_ASSERT(host.cmp("foo.com") == 0); + GPR_ASSERT(port.cmp("5555") == 0); grpc_uri_destroy(sts_url); } From 9f59029aee2d613002b650420ef7dc0129991ad7 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Thu, 27 Jun 2019 20:54:51 -0700 Subject: [PATCH 509/676] Revert the implementation of grpc_iomgr_run_in_background() for gevent, which causes duplicate definitions. --- src/core/lib/iomgr/iomgr_custom.cc | 2 -- src/core/lib/iomgr/iomgr_uv.cc | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 262417cf0d2..f5ac8a0670a 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -72,8 +72,6 @@ void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_set_iomgr_platform_vtable(&vtable); } -bool grpc_iomgr_run_in_background() { return false; } - #ifdef GRPC_CUSTOM_SOCKET grpc_iomgr_platform_vtable* grpc_default_iomgr_platform_vtable() { return &vtable; diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc index 4a984446dba..d00bfa4d46e 100644 --- a/src/core/lib/iomgr/iomgr_uv.cc +++ b/src/core/lib/iomgr/iomgr_uv.cc @@ -37,4 +37,6 @@ void grpc_set_default_iomgr_platform() { grpc_custom_iomgr_init(&grpc_uv_socket_vtable, &uv_resolver_vtable, &uv_timer_vtable, &uv_pollset_vtable); } + +bool grpc_iomgr_run_in_background() { return false; } #endif From 743be2ba94f37366f48f2465e69e8d7a4c14b864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=A2=E3=83=8F=E3=83=A1=E3=83=89?= <12945919+iamrare@users.noreply.github.com> Date: Fri, 28 Jun 2019 15:54:03 +0900 Subject: [PATCH 510/676] fix link --- doc/statuscodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 61e0d820b48..a5c395d0ceb 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -71,4 +71,4 @@ The following status codes are never generated by the library: - OUT_OF_RANGE - DATA_LOSS -Applications that may wish to [retry](https:github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. +Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. From 4c96998eb1cd263396d0f3b1c4af43bfbbc859c3 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 26 Jun 2019 16:07:03 -0700 Subject: [PATCH 511/676] Fix typo --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 19 ++++++++++--------- src/core/lib/iomgr/iocp_windows.cc | 4 ++-- src/core/lib/iomgr/socket_windows.h | 2 +- src/core/lib/iomgr/tcp_windows.cc | 14 +++++++------- tools/interop_matrix/client_matrix.py | 2 +- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index d24c111448c..addae23dc3e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -459,12 +459,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd { connect_done_ = true; GPR_ASSERT(wsa_connect_error_ == 0); if (error == GRPC_ERROR_NONE) { - DWORD transfered_bytes = 0; + DWORD transferred_bytes = 0; DWORD flags; - BOOL wsa_success = WSAGetOverlappedResult( - grpc_winsocket_wrapped_socket(winsocket_), - &winsocket_->write_info.overlapped, &transfered_bytes, FALSE, &flags); - GPR_ASSERT(transfered_bytes == 0); + BOOL wsa_success = + WSAGetOverlappedResult(grpc_winsocket_wrapped_socket(winsocket_), + &winsocket_->write_info.overlapped, + &transferred_bytes, FALSE, &flags); + GPR_ASSERT(transferred_bytes == 0); if (!wsa_success) { wsa_connect_error_ = WSAGetLastError(); char* msg = gpr_format_message(wsa_connect_error_); @@ -620,8 +621,8 @@ class GrpcPolledFdWindows : public GrpcPolledFd { } } if (error == GRPC_ERROR_NONE) { - read_buf_ = grpc_slice_sub_no_ref(read_buf_, 0, - winsocket_->read_info.bytes_transfered); + read_buf_ = grpc_slice_sub_no_ref( + read_buf_, 0, winsocket_->read_info.bytes_transferred); read_buf_has_data_ = true; } else { grpc_slice_unref_internal(read_buf_); @@ -657,9 +658,9 @@ class GrpcPolledFdWindows : public GrpcPolledFd { if (error == GRPC_ERROR_NONE) { tcp_write_state_ = WRITE_WAITING_FOR_VERIFICATION_UPON_RETRY; write_buf_ = grpc_slice_sub_no_ref( - write_buf_, 0, winsocket_->write_info.bytes_transfered); + write_buf_, 0, winsocket_->write_info.bytes_transferred); GRPC_CARES_TRACE_LOG("fd:|%s| OnIocpWriteableInner. bytes transferred:%d", - GetName(), winsocket_->write_info.bytes_transfered); + GetName(), winsocket_->write_info.bytes_transferred); } else { grpc_slice_unref_internal(write_buf_); write_buf_ = grpc_empty_slice(); diff --git a/src/core/lib/iomgr/iocp_windows.cc b/src/core/lib/iomgr/iocp_windows.cc index ad325fe2156..29a05ee3099 100644 --- a/src/core/lib/iomgr/iocp_windows.cc +++ b/src/core/lib/iomgr/iocp_windows.cc @@ -90,12 +90,12 @@ grpc_iocp_work_status grpc_iocp_work(grpc_millis deadline) { abort(); } if (socket->shutdown_called) { - info->bytes_transfered = 0; + info->bytes_transferred = 0; info->wsa_error = WSA_OPERATION_ABORTED; } else { success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); - info->bytes_transfered = bytes; + info->bytes_transferred = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); } GPR_ASSERT(overlapped == &info->overlapped); diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 5fed6909e6f..78f79453c6c 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -59,7 +59,7 @@ typedef struct grpc_winsocket_callback_info { to hold a mutex for a long amount of time. */ int has_pending_iocp; /* The results of the overlapped operation. */ - DWORD bytes_transfered; + DWORD bytes_transferred; int wsa_error; } grpc_winsocket_callback_info; diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index ae6b2b68e62..32d0bb36ea7 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -196,17 +196,17 @@ static void on_read(void* tcpp, grpc_error* error) { gpr_free(utf8_message); grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); } else { - if (info->bytes_transfered != 0 && !tcp->shutting_down) { - GPR_ASSERT((size_t)info->bytes_transfered <= tcp->read_slices->length); - if (static_cast(info->bytes_transfered) != + if (info->bytes_transferred != 0 && !tcp->shutting_down) { + GPR_ASSERT((size_t)info->bytes_transferred <= tcp->read_slices->length); + if (static_cast(info->bytes_transferred) != tcp->read_slices->length) { grpc_slice_buffer_trim_end( tcp->read_slices, tcp->read_slices->length - - static_cast(info->bytes_transfered), + static_cast(info->bytes_transferred), &tcp->last_read_buffer); } - GPR_ASSERT((size_t)info->bytes_transfered == tcp->read_slices->length); + GPR_ASSERT((size_t)info->bytes_transferred == tcp->read_slices->length); if (grpc_tcp_trace.enabled()) { size_t i; @@ -288,7 +288,7 @@ static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, /* Did we get data immediately ? Yay. */ if (info->wsa_error != WSAEWOULDBLOCK) { - info->bytes_transfered = bytes_read; + info->bytes_transferred = bytes_read; GRPC_CLOSURE_SCHED(&tcp->on_read, GRPC_ERROR_NONE); return; } @@ -333,7 +333,7 @@ static void on_write(void* tcpp, grpc_error* error) { if (info->wsa_error != 0) { error = GRPC_WSA_ERROR(info->wsa_error, "WSASend"); } else { - GPR_ASSERT(info->bytes_transfered == tcp->write_slices->length); + GPR_ASSERT(info->bytes_transferred == tcp->write_slices->length); } } diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 7bcfa075559..d6d0612b4e4 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -284,7 +284,7 @@ LANG_RELEASE_MATRIX = { ('v1.16.0', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.17.1', ReleaseInfo(testcases_file='php__v1.0.1')), ('v1.18.0', ReleaseInfo()), - # v1.19 and v1.20 were deliberately ommitted here because of an issue. + # v1.19 and v1.20 were deliberately omitted here because of an issue. # See https://github.com/grpc/grpc/issues/18264 ('v1.21.4', ReleaseInfo()), ]), From d527c1fbda718e7e274de4c5ec300c0345dea7b6 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 26 Jun 2019 17:41:39 -0700 Subject: [PATCH 512/676] Pre-compute static metadata index for hpack_encoder. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally, hpack_encoder would check if a metadata was static or not by comparing its pointer to the known static metadata global table and checking if it was within bounds. This check was performed regardless of if the metadata was static or not, and is somewhat costly. Instead, we now pre-compute the static metadata index during code generation time, and store it with static metadata objects. We read that value only if we are dealing with a static metadata flag (which we know from the storage type of the grpc_mdelem). This yields slightly faster metadata encoding: BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:0 ] 34.9ns ± 2% 34.2ns ± 1% -2.04% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader/1/16384 [framing_bytes/iter:9 header_bytes/iter:0 ] 34.9ns ± 2% 34.2ns ± 1% -2.01% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.6ns ± 0% 49.2ns ± 2% -2.74% (p=0.000 n=18+20) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:6 ] 84.7ns ± 1% 83.5ns ± 1% -1.43% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.4ns ± 0% 47.9ns ± 0% -4.83% (p=0.000 n=18+17) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 51.1ns ± 2% 48.9ns ± 1% -4.32% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.8ns ± 2% 48.8ns ± 2% -3.88% (p=0.000 n=19+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.2ns ± 1% 47.9ns ± 0% -4.47% (p=0.000 n=19+16) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.2ns ± 0% 47.9ns ± 0% -4.46% (p=0.000 n=18+16) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.2ns ± 0% 47.9ns ± 0% -4.40% (p=0.000 n=19+17) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.7ns ± 2% 48.8ns ± 2% -3.81% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.9ns ± 2% 48.8ns ± 2% -4.05% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.1ns ± 0% 48.0ns ± 1% -4.27% (p=0.000 n=17+17) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.1ns ± 0% 48.0ns ± 1% -4.28% (p=0.000 n=18+17) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.1ns ± 0% 48.0ns ± 0% -4.33% (p=0.000 n=18+17) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:9 ] 91.4ns ± 1% 90.7ns ± 1% -0.79% (p=0.000 n=18+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:12 ] 116ns ± 1% 116ns ± 1% -0.46% (p=0.002 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:14 ] 122ns ± 0% 121ns ± 0% -0.69% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:23 ] 144ns ± 1% 144ns ± 0% -0.23% (p=0.009 n=20+20) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:46 ] 232ns ± 0% 232ns ± 1% -0.26% (p=0.021 n=18+19) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:12 ] 92.9ns ± 1% 92.0ns ± 1% -0.97% (p=0.000 n=19+19) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:14 ] 94.0ns ± 1% 92.6ns ± 1% -1.45% (p=0.000 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:21 ] 93.9ns ± 2% 92.8ns ± 1% -1.17% (p=0.001 n=20+19) BM_HpackEncoderEncodeHeader>/0/16384 [framing_bytes/iter:9 header_bytes/iter:111 ] 106ns ± 0% 105ns ± 3% -1.15% (p=0.000 n=18+20) BM_HpackEncoderEncodeHeader/0/1 [framing_bytes/iter:81 header_bytes/iter:9 ] 355ns ± 1% 354ns ± 0% -0.35% (p=0.015 n=19+20) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:8.00002 ] 139ns ± 1% 133ns ± 1% -4.46% (p=0.000 n=19+20) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:16 ] 236ns ± 1% 231ns ± 1% -2.24% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader/0/16384 [framing_bytes/iter:9 header_bytes/iter:3 ] 73.6ns ± 1% 70.5ns ± 1% -4.14% (p=0.000 n=20+20) BM_HpackEncoderEncodeHeader/1/16384 [framing_bytes/iter:9 header_bytes/iter:1 ] 50.5ns ± 0% 49.2ns ± 2% -2.60% (p=0.000 n=16+20) --- .../chttp2/transport/hpack_encoder.cc | 22 ++- src/core/lib/transport/metadata.h | 6 +- src/core/lib/transport/static_metadata.cc | 172 +++++++++--------- tools/codegen/core/gen_static_metadata.py | 6 +- 4 files changed, 109 insertions(+), 97 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 359ad275bbb..9e5f0f5e4a1 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -711,18 +711,28 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_mdelem md = *extra_headers[i]; - uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(md); - if (static_index) { - emit_indexed(c, static_cast(static_index), &st); + const bool is_static = + GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC; + uintptr_t static_index; + if (is_static && + (static_index = + reinterpret_cast(GRPC_MDELEM_DATA(md)) + ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + emit_indexed(c, static_cast(static_index + 1), &st); } else { hpack_enc(c, md, &st); } } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - uintptr_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md); - if (static_index) { - emit_indexed(c, static_cast(static_index), &st); + const bool is_static = + GRPC_MDELEM_STORAGE(l->md) == GRPC_MDELEM_STORAGE_STATIC; + uintptr_t static_index; + if (is_static && + (static_index = reinterpret_cast( + GRPC_MDELEM_DATA(l->md)) + ->StaticIndex()) < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + emit_indexed(c, static_cast(static_index + 1), &st); } else { hpack_enc(c, l->md, &st); } diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 4b9685066e5..4621433bf01 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -186,19 +186,21 @@ struct UserData { class StaticMetadata { public: - StaticMetadata(const grpc_slice& key, const grpc_slice& value) - : kv_({key, value}), hash_(0) {} + StaticMetadata(const grpc_slice& key, const grpc_slice& value, uintptr_t idx) + : kv_({key, value}), hash_(0), static_idx_(idx) {} const grpc_mdelem_data& data() const { return kv_; } void HashInit(); uint32_t hash() { return hash_; } + uintptr_t StaticIndex() { return static_idx_; } private: grpc_mdelem_data kv_; /* private only data */ uint32_t hash_; + uintptr_t static_idx_; }; class RefcountedMdBase { diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index bbf1736b595..5887e3515fb 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -398,262 +398,262 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b) { grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 0), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}), + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}, 1), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}), + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}, 2), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, - {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}), + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}, 3), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, - {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}), + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}, 4), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}), + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}, 5), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}), + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}, 6), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}), + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}, 7), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}), + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}, 8), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}), + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}, 9), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}), + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}, 10), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}), + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}, 11), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}), + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}, 12), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, - {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}), + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}, 13), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 14), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}), + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}, 15), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 16), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 17), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 18), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 19), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 20), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 21), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 22), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 23), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 24), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 25), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 26), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 27), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 28), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 29), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 30), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 31), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 32), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 33), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 34), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 35), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 36), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 37), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 38), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 39), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 40), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 41), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 42), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 43), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 44), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 45), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 46), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 47), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 48), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 49), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 50), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 51), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 52), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 53), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 54), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 55), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 56), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 57), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 58), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 59), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 60), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}), + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}, 61), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}), + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}, 62), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, - {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}), + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}, 63), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 64), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 65), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, - {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}), + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, 66), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, - {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}), + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}, 67), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, - {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}), + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}, 68), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, - {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}), + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}, 69), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, - {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}), + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}, 70), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 71), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 72), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 73), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 74), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, - {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}), + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, 75), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 76), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}), + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, 77), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}), + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}, 78), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 79), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}), + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, 80), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}), + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}, 81), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, - {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}), + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}, 82), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}), + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, 83), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}), + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, 84), grpc_core::StaticMetadata( {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, - {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}), + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, 85), }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index b534d8dab7e..a149e001d75 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -550,9 +550,9 @@ print >> C, '}' print >> C print >> C, 'grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for a, b in all_elems: - print >> C, 'grpc_core::StaticMetadata(%s,%s),' % (slice_def(str_idx(a)), - slice_def(str_idx(b))) +for idx, (a, b) in enumerate(all_elems): + print >> C, 'grpc_core::StaticMetadata(%s,%s, %d),' % ( + slice_def(str_idx(a)), slice_def(str_idx(b)), idx) print >> C, '};' print >> H, 'typedef enum {' From 74be06c80f5bd9562041b1f3c6359a7ebf3620d0 Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Sun, 30 Jun 2019 09:42:21 +0100 Subject: [PATCH 513/676] remove UTF8 byte[] allocations: decode directly into a string; encode using stack or array-pool --- .../Grpc.Core/Internal/CallSafeHandle.cs | 37 +++++++++++++++++-- src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 33 +++++++++++------ .../Internal/NativeMethods.Generated.cs | 16 +++++--- 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 858d2a69605..67efb031629 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -21,6 +21,7 @@ using System.Text; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Core.Profiling; +using System.Buffers; namespace Grpc.Core.Internal { @@ -127,16 +128,44 @@ namespace Grpc.Core.Internal } } - public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, + public unsafe void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags) { using (completionQueue.NewScope()) { var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback); var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; - var statusDetailBytes = MarshalUtils.GetBytesUTF8(status.Detail); - Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata ? 1 : 0, - optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + int maxBytes = MarshalUtils.GetMaxBytesUTF8(status.Detail); + const int MaxStackAllocBytes = 256; + + if (maxBytes <= MaxStackAllocBytes) + { // for small status, we can encode on the stack without touching arrays + // note: if init-locals is disabled, it would be more efficient + // to just stackalloc[MaxStackAllocBytes]; but by default, since we + // expect this to be small and it needs to wipe, just use maxBytes + byte* ptr = stackalloc byte[maxBytes]; + int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); + Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, ptr, new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, + optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + } + else + { // for larger status (rare), rent a buffer from the pool and + // use that for encoding + var statusBuffer = ArrayPool.Shared.Rent(maxBytes); + try + { + fixed (byte* ptr = statusBuffer) + { + int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); + Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, ptr, new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, + optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + } + } + finally + { + ArrayPool.Shared.Return(statusBuffer); + } + } } } diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index e3e41617955..ec3ce9ca72d 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -32,34 +32,43 @@ namespace Grpc.Core.Internal /// /// Converts IntPtr pointing to a UTF-8 encoded byte array to string. /// - public static string PtrToStringUTF8(IntPtr ptr, int len) + public static unsafe string PtrToStringUTF8(IntPtr ptr, int len) { if (len == 0) { return ""; } - // TODO(jtattermusch): once Span dependency is added, - // use Span-based API to decode the string without copying the buffer. - var bytes = new byte[len]; - Marshal.Copy(ptr, bytes, 0, len); - return EncodingUTF8.GetString(bytes); + // allocate a right-sized string and decode into it + byte* source = (byte*)ptr.ToPointer(); + int charCount = EncodingUTF8.GetCharCount(source, len); + string s = new string('\0', charCount); + fixed(char* cPtr = s) + { + EncodingUTF8.GetChars(source, len, cPtr, charCount); + } + return s; } /// - /// Returns byte array containing UTF-8 encoding of given string. + /// UTF-8 encodes the given string into a buffer of sufficient size /// - public static byte[] GetBytesUTF8(string str) + public static unsafe int GetBytesUTF8(string str, byte* destination, int destinationLength) { - return EncodingUTF8.GetBytes(str); + int charCount = str.Length; + if (charCount == 0) return 0; + fixed (char* source = str) + { + return EncodingUTF8.GetBytes(source, charCount, destination, destinationLength); + } } /// - /// Get string from a UTF8 encoded byte array. + /// Returns the maximum number of bytes required to encode a given string. /// - public static string GetStringUTF8(byte[] bytes) + public static int GetMaxBytesUTF8(string str) { - return EncodingUTF8.GetString(bytes); + return EncodingUTF8.GetMaxByteCount(str.Length); } } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index b8a60b31c40..e67263edbda 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -266,7 +266,10 @@ namespace Grpc.Core.Internal this.grpcsharp_call_start_duplex_streaming = DllImportsFromStaticLib.grpcsharp_call_start_duplex_streaming; this.grpcsharp_call_send_message = DllImportsFromStaticLib.grpcsharp_call_send_message; this.grpcsharp_call_send_close_from_client = DllImportsFromStaticLib.grpcsharp_call_send_close_from_client; - this.grpcsharp_call_send_status_from_server = DllImportsFromStaticLib.grpcsharp_call_send_status_from_server; + unsafe + { + this.grpcsharp_call_send_status_from_server = DllImportsFromStaticLib.grpcsharp_call_send_status_from_server; + } this.grpcsharp_call_recv_message = DllImportsFromStaticLib.grpcsharp_call_recv_message; this.grpcsharp_call_recv_initial_metadata = DllImportsFromStaticLib.grpcsharp_call_recv_initial_metadata; this.grpcsharp_call_start_serverside = DllImportsFromStaticLib.grpcsharp_call_start_serverside; @@ -366,7 +369,10 @@ namespace Grpc.Core.Internal this.grpcsharp_call_start_duplex_streaming = DllImportsFromSharedLib.grpcsharp_call_start_duplex_streaming; this.grpcsharp_call_send_message = DllImportsFromSharedLib.grpcsharp_call_send_message; this.grpcsharp_call_send_close_from_client = DllImportsFromSharedLib.grpcsharp_call_send_close_from_client; - this.grpcsharp_call_send_status_from_server = DllImportsFromSharedLib.grpcsharp_call_send_status_from_server; + unsafe + { + this.grpcsharp_call_send_status_from_server = DllImportsFromSharedLib.grpcsharp_call_send_status_from_server; + } this.grpcsharp_call_recv_message = DllImportsFromSharedLib.grpcsharp_call_recv_message; this.grpcsharp_call_recv_initial_metadata = DllImportsFromSharedLib.grpcsharp_call_recv_initial_metadata; this.grpcsharp_call_start_serverside = DllImportsFromSharedLib.grpcsharp_call_start_serverside; @@ -469,7 +475,7 @@ namespace Grpc.Core.Internal public delegate CallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags); public delegate CallError grpcsharp_call_send_message_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata); public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); - public delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public unsafe delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); public delegate CallError grpcsharp_call_recv_message_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); public delegate CallError grpcsharp_call_recv_initial_metadata_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); public delegate CallError grpcsharp_call_start_serverside_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); @@ -637,7 +643,7 @@ namespace Grpc.Core.Internal public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public static unsafe extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); [DllImport(ImportName)] public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx); @@ -933,7 +939,7 @@ namespace Grpc.Core.Internal public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public static unsafe extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); [DllImport(ImportName)] public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx); From cb813e1ffce4498a51fe87487554669dfdcb3903 Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Sun, 30 Jun 2019 09:59:46 +0100 Subject: [PATCH 514/676] check the *actual* length to allow more stack usage *and* allow smaller pool rentals --- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 ++ src/csharp/Grpc.Core/Internal/CallSafeHandle.cs | 10 +++++++++- src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index afd60e73a21..1844ce335bc 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -100,6 +100,8 @@ + + diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 67efb031629..c62297b0972 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -135,8 +135,16 @@ namespace Grpc.Core.Internal { var ctx = completionQueue.CompletionRegistry.RegisterBatchCompletion(CompletionHandler_ISendStatusFromServerCompletionCallback, callback); var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; - int maxBytes = MarshalUtils.GetMaxBytesUTF8(status.Detail); + const int MaxStackAllocBytes = 256; + int maxBytes = MarshalUtils.GetMaxByteCountUTF8(status.Detail); + if (maxBytes > MaxStackAllocBytes) + { + // pay the extra to get the *actual* size; this could mean that + // it ends up fitting on the stack after all, but even if not + // it will mean that we ask for a *much* smaller buffer + maxBytes = MarshalUtils.GetByteCountUTF8(status.Detail); + } if (maxBytes <= MaxStackAllocBytes) { // for small status, we can encode on the stack without touching arrays diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index ec3ce9ca72d..54b4370935d 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -66,9 +66,17 @@ namespace Grpc.Core.Internal /// /// Returns the maximum number of bytes required to encode a given string. /// - public static int GetMaxBytesUTF8(string str) + public static int GetMaxByteCountUTF8(string str) { return EncodingUTF8.GetMaxByteCount(str.Length); } + + /// + /// Returns the actual number of bytes required to encode a given string. + /// + public static int GetByteCountUTF8(string str) + { + return EncodingUTF8.GetByteCount(str); + } } } From 05a0dd20e4be4f0715be74ee092040fd6b05f173 Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 14:58:11 +0100 Subject: [PATCH 515/676] convert micro-benchmarks to benchmarkdotnet --- .gitignore | 3 + .../CommonThreadedBase.cs | 67 ++++++++++++++ .../CompletionRegistryBenchmark.cs | 56 ++++-------- src/csharp/Grpc.Microbenchmarks/GCStats.cs | 69 -------------- .../Grpc.Microbenchmarks.csproj | 7 +- .../PInvokeByteArrayBenchmark.cs | 38 +++----- src/csharp/Grpc.Microbenchmarks/Program.cs | 89 ++----------------- .../SendMessageBenchmark.cs | 39 +++----- .../Grpc.Microbenchmarks/ThreadedBenchmark.cs | 65 -------------- 9 files changed, 123 insertions(+), 310 deletions(-) create mode 100644 src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs delete mode 100644 src/csharp/Grpc.Microbenchmarks/GCStats.cs delete mode 100644 src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs diff --git a/.gitignore b/.gitignore index a8c58277c34..4a400b4e3b4 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,6 @@ bm_*.json # Clion artifacts cmake-build-debug/ + +# Benchmark outputs +BenchmarkDotNet.Artifacts/ \ No newline at end of file diff --git a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs new file mode 100644 index 00000000000..d8724f1eaad --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs @@ -0,0 +1,67 @@ +#region Copyright notice and license + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Grpc.Core; + +namespace Grpc.Microbenchmarks +{ + + // common base-type for tests that need to run with some level of concurrency; + // note there's nothing *special* about this type - it is just to save some + // boilerplate + + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + [ShortRunJob] // don't take too long + public abstract class CommonThreadedBase + { + protected virtual bool NeedsEnvironment => true; + + [Params(1, 1, 2, 4, 8, 12)] + public int ThreadCount { get; set; } + + protected GrpcEnvironment Environment { get; private set; } + + [GlobalSetup] + public virtual void Setup() + { + ThreadPool.GetMinThreads(out var workers, out var iocp); + if (workers <= ThreadCount) ThreadPool.SetMinThreads(ThreadCount + 1, iocp); + if (NeedsEnvironment) Environment = GrpcEnvironment.AddRef(); + } + + [GlobalCleanup] + public virtual void Cleanup() + { + if (Environment != null) + { + Environment = null; + GrpcEnvironment.ReleaseAsync().Wait(); + } + } + + protected void RunConcurrent(Action operation) + { + Parallel.For(0, ThreadCount, _ => operation()); + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index bb57a6968fa..58ba29927cc 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -17,62 +17,38 @@ #endregion using System; -using System.Runtime.InteropServices; -using System.Threading; -using Grpc.Core; +using BenchmarkDotNet.Attributes; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class CompletionRegistryBenchmark + public class CompletionRegistryBenchmarks : CommonThreadedBase { - GrpcEnvironment environment; + [Params(false, true)] + public bool UseSharedRegistry { get; set; } - public void Init() + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public void Run() { - environment = GrpcEnvironment.AddRef(); + RunConcurrent(() => { + CompletionRegistry sharedRegistry = UseSharedRegistry ? new CompletionRegistry(Environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; + RunBody(sharedRegistry); + }); } - public void Cleanup() + private void RunBody(CompletionRegistry optionalSharedRegistry) { - GrpcEnvironment.ReleaseAsync().Wait(); - } - - public void Run(int threadCount, int iterations, bool useSharedRegistry) - { - Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry)); - CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry)); - threadedBenchmark.Run(); - // TODO: parametrize by number of pending completions - } - - private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry) - { - var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment, () => throw new NotImplementedException(), () => throw new NotImplementedException()); + var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(Environment, () => throw new NotImplementedException(), () => throw new NotImplementedException()); var ctx = BatchContextSafeHandle.Create(); - - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + + for (int i = 0; i < Iterations; i++) { completionRegistry.Register(ctx.Handle, ctx); var callback = completionRegistry.Extract(ctx.Handle); // NOTE: we are not calling the callback to avoid disposing ctx. } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); - ctx.Recycle(); } - - private class NopCompletionCallback : IOpCompletionCallback - { - public void OnComplete(bool success) - { - - } - } } } diff --git a/src/csharp/Grpc.Microbenchmarks/GCStats.cs b/src/csharp/Grpc.Microbenchmarks/GCStats.cs deleted file mode 100644 index ca7051ec4e5..00000000000 --- a/src/csharp/Grpc.Microbenchmarks/GCStats.cs +++ /dev/null @@ -1,69 +0,0 @@ -#region Copyright notice and license - -// Copyright 2015 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#endregion - -using System; -using Grpc.Core; -using Grpc.Core.Internal; - -namespace Grpc.Microbenchmarks -{ - internal class GCStats - { - readonly object myLock = new object(); - GCStatsSnapshot lastSnapshot; - - public GCStats() - { - lastSnapshot = new GCStatsSnapshot(GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2)); - } - - public GCStatsSnapshot GetSnapshot(bool reset = false) - { - lock (myLock) - { - var newSnapshot = new GCStatsSnapshot(GC.CollectionCount(0) - lastSnapshot.Gen0, - GC.CollectionCount(1) - lastSnapshot.Gen1, - GC.CollectionCount(2) - lastSnapshot.Gen2); - if (reset) - { - lastSnapshot = newSnapshot; - } - return newSnapshot; - } - } - } - - public class GCStatsSnapshot - { - public GCStatsSnapshot(int gen0, int gen1, int gen2) - { - this.Gen0 = gen0; - this.Gen1 = gen1; - this.Gen2 = gen2; - } - - public int Gen0 { get; } - public int Gen1 { get; } - public int Gen2 { get; } - - public override string ToString() - { - return string.Format("[GCCollectionCount: gen0 {0}, gen1 {1}, gen2 {2}]", Gen0, Gen1, Gen2); - } - } -} diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index e0fcdecd9ac..899e41ce532 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -3,7 +3,7 @@ - net45;netcoreapp2.1 + net461;netcoreapp2.1 Exe true @@ -13,10 +13,10 @@ - + - + @@ -24,5 +24,4 @@ - diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs index 787b5508fba..412f9ad1cb4 100644 --- a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -16,49 +16,39 @@ #endregion -using System; using System.Runtime.InteropServices; -using System.Threading; -using Grpc.Core; +using BenchmarkDotNet.Attributes; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class PInvokeByteArrayBenchmark + public class PInvokeByteArrayBenchmark : CommonThreadedBase { static readonly NativeMethods Native = NativeMethods.Get(); - public void Init() - { - } + protected override bool NeedsEnvironment => false; - public void Cleanup() - { - } - public void Run(int threadCount, int iterations, int payloadSize) + [Params(0)] + public int PayloadSize { get; set; } + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public void Run() { - Console.WriteLine(string.Format("PInvokeByteArrayBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize)); - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize)); - threadedBenchmark.Run(); + RunConcurrent(RunBody); } - private void ThreadBody(int iterations, int payloadSize) + private void RunBody() { - var payload = new byte[payloadSize]; - - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + var payload = new byte[PayloadSize]; + for (int i = 0; i < Iterations; i++) { var gcHandle = GCHandle.Alloc(payload, GCHandleType.Pinned); var payloadPtr = gcHandle.AddrOfPinnedObject(); Native.grpcsharp_test_nop(payloadPtr); gcHandle.Free(); } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); } } } diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs index a64c2979abe..71e549f76ff 100644 --- a/src/csharp/Grpc.Microbenchmarks/Program.cs +++ b/src/csharp/Grpc.Microbenchmarks/Program.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -16,95 +16,18 @@ #endregion -using System; -using Grpc.Core; -using Grpc.Core.Internal; -using Grpc.Core.Logging; -using CommandLine; -using CommandLine.Text; +using BenchmarkDotNet.Running; namespace Grpc.Microbenchmarks { class Program { - public enum MicrobenchmarkType - { - CompletionRegistry, - PInvokeByteArray, - SendMessage - } - - private class BenchmarkOptions - { - [Option("benchmark", Required = true, HelpText = "Benchmark to run")] - public MicrobenchmarkType Benchmark { get; set; } - } - + // typical usage: dotnet run -c Release -f netcoreapp2.1 + // (this will profile both .net core and .net framework; for some reason + // if you start from "-f net461", it goes horribly wrong) public static void Main(string[] args) { - GrpcEnvironment.SetLogger(new ConsoleLogger()); - var parserResult = Parser.Default.ParseArguments(args) - .WithNotParsed(errors => { - Console.WriteLine("Supported benchmarks:"); - foreach (var enumValue in Enum.GetValues(typeof(MicrobenchmarkType))) - { - Console.WriteLine(" " + enumValue); - } - Environment.Exit(1); - }) - .WithParsed(options => - { - switch (options.Benchmark) - { - case MicrobenchmarkType.CompletionRegistry: - RunCompletionRegistryBenchmark(); - break; - case MicrobenchmarkType.PInvokeByteArray: - RunPInvokeByteArrayBenchmark(); - break; - case MicrobenchmarkType.SendMessage: - RunSendMessageBenchmark(); - break; - default: - throw new ArgumentException("Unsupported benchmark."); - } - }); - } - - static void RunCompletionRegistryBenchmark() - { - var benchmark = new CompletionRegistryBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - foreach (bool useSharedRegistry in new bool[] {false, true}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, useSharedRegistry); - } - } - benchmark.Cleanup(); - } - - static void RunPInvokeByteArrayBenchmark() - { - var benchmark = new PInvokeByteArrayBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, 0); - } - benchmark.Cleanup(); - } - - static void RunSendMessageBenchmark() - { - var benchmark = new SendMessageBenchmark(); - benchmark.Init(); - foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) - { - benchmark.Run(threadCount, 4 * 1000 * 1000, 0); - } - benchmark.Cleanup(); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); } } } diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index 390c062298d..fa06e7a8230 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -17,59 +17,48 @@ #endregion using System; -using System.Threading; +using BenchmarkDotNet.Attributes; using Grpc.Core; using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; namespace Grpc.Microbenchmarks { - public class SendMessageBenchmark + public class SendMessageBenchmark : CommonThreadedBase { static readonly NativeMethods Native = NativeMethods.Get(); - GrpcEnvironment environment; - - public void Init() + public override void Setup() { Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop"); - environment = GrpcEnvironment.AddRef(); + base.Setup(); } - public void Cleanup() - { - GrpcEnvironment.ReleaseAsync().Wait(); - // TODO(jtattermusch): track GC stats - } + [Params(0)] + public int PayloadSize { get; set; } - public void Run(int threadCount, int iterations, int payloadSize) + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public void Run() { - Console.WriteLine(string.Format("SendMessageBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize)); - var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize)); - threadedBenchmark.Run(); + RunConcurrent(RunBody); } - private void ThreadBody(int iterations, int payloadSize) + private void RunBody() { - var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); + var completionRegistry = new CompletionRegistry(Environment, () => Environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); var call = CreateFakeCall(cq); var sendCompletionCallback = new NopSendCompletionCallback(); - var payload = new byte[payloadSize]; + var payload = new byte[PayloadSize]; var writeFlags = default(WriteFlags); - var stopwatch = Stopwatch.StartNew(); - for (int i = 0; i < iterations; i++) + for (int i = 0; i < Iterations; i++) { call.StartSendMessage(sendCompletionCallback, payload, writeFlags, false); var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey); callback.OnComplete(true); } - stopwatch.Stop(); - Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); - cq.Dispose(); } diff --git a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs deleted file mode 100644 index 95b9aaaf3f9..00000000000 --- a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs +++ /dev/null @@ -1,65 +0,0 @@ -#region Copyright notice and license - -// Copyright 2015 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#endregion - -using System; -using System.Threading; -using Grpc.Core; -using Grpc.Core.Internal; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Grpc.Microbenchmarks -{ - public class ThreadedBenchmark - { - List runners; - - public ThreadedBenchmark(IEnumerable runners) - { - this.runners = new List(runners); - } - - public ThreadedBenchmark(int threadCount, Action threadBody) - { - this.runners = new List(); - for (int i = 0; i < threadCount; i++) - { - this.runners.Add(new ThreadStart(() => threadBody())); - } - } - - public void Run() - { - Console.WriteLine("Running threads."); - var gcStats = new GCStats(); - var threads = new List(); - for (int i = 0; i < runners.Count; i++) - { - var thread = new Thread(runners[i]); - thread.Start(); - threads.Add(thread); - } - - foreach (var thread in threads) - { - thread.Join(); - } - Console.WriteLine("All threads finished (GC Stats Delta: " + gcStats.GetSnapshot() + ")"); - } - } -} From 52de8a0a17ebcfe414cbb777c3861cb3142577ec Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 15:25:22 +0100 Subject: [PATCH 516/676] ShortRunJob *added* a test! --- src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs index d8724f1eaad..4b6174eeef8 100644 --- a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs +++ b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs @@ -31,7 +31,6 @@ namespace Grpc.Microbenchmarks [ClrJob, CoreJob] // test .NET Core and .NET Framework [MemoryDiagnoser] // allocations - [ShortRunJob] // don't take too long public abstract class CommonThreadedBase { protected virtual bool NeedsEnvironment => true; From f5091b2622d57fb34fc30fec1f609fe7b8d74800 Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 16:16:00 +0100 Subject: [PATCH 517/676] add UTF8-decode benchmark | Method | Job | Runtime | PayloadSize | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | |------- |----- |-------- |------------ |-------------:|-----------:|-----------:|-------:|------:|------:|----------:| | Run | Clr | Clr | 0 | 1.736 ns | 0.0101 ns | 0.0094 ns | - | - | - | - | | Run | Core | Core | 0 | 1.306 ns | 0.0108 ns | 0.0095 ns | - | - | - | - | | Run | Clr | Clr | 1 | 35.384 ns | 0.2282 ns | 0.2135 ns | 0.0101 | - | - | 64 B | | Run | Core | Core | 1 | 32.388 ns | 0.3333 ns | 0.2955 ns | 0.0101 | - | - | 64 B | | Run | Clr | Clr | 4 | 57.736 ns | 0.3889 ns | 0.3448 ns | 0.0114 | - | - | 72 B | | Run | Core | Core | 4 | 52.878 ns | 0.2802 ns | 0.2621 ns | 0.0114 | - | - | 72 B | | Run | Clr | Clr | 128 | 554.819 ns | 4.4341 ns | 4.1477 ns | 0.0830 | - | - | 530 B | | Run | Core | Core | 128 | 336.356 ns | 1.6148 ns | 1.4315 ns | 0.0835 | - | - | 528 B | | Run | Clr | Clr | 1024 | 4,050.850 ns | 28.9245 ns | 25.6408 ns | 0.6016 | - | - | 3820 B | | Run | Core | Core | 1024 | 2,272.534 ns | 33.8963 ns | 31.7066 ns | 0.6016 | - | - | 3808 B | --- .../Grpc.Microbenchmarks.csproj | 1 + src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 899e41ce532..f775e4c85fb 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -6,6 +6,7 @@ net461;netcoreapp2.1 Exe true + true diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs new file mode 100644 index 00000000000..1c3f4d261ee --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; +using BenchmarkDotNet.Attributes; +using Grpc.Core.Internal; + +namespace Grpc.Microbenchmarks +{ + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class Utf8Decode + { + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize { get; set; } + + static readonly Dictionary Payloads = new Dictionary { + { 0, Invent(0) }, + { 1, Invent(1) }, + { 4, Invent(4) }, + { 128, Invent(128) }, + { 1024, Invent(1024) }, + }; + + static byte[] Invent(int length) + { + var rand = new Random(Seed: length); + var chars = new char[length]; + for(int i = 0; i < chars.Length; i++) + { + chars[i] = (char)rand.Next(32, 300); + } + return Encoding.UTF8.GetBytes(chars); + } + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public unsafe void Run() + { + byte[] payload = Payloads[PayloadSize]; + fixed (byte* ptr = payload) + { + var iPtr = new IntPtr(ptr); + for (int i = 0; i < Iterations; i++) + { + MarshalUtils.PtrToStringUTF8(iPtr, payload.Length); + } + } + } + } +} From dbef6c9c70898451dbc1eadfb7e1bab0a9d18a42 Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 16:36:46 +0100 Subject: [PATCH 518/676] add utf-8 encode benchmark --- .../Properties/AssemblyInfo.cs | 6 ++ .../Grpc.Microbenchmarks.csproj | 1 + src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 72 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs diff --git a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs index af264c9be5d..e19010f0509 100644 --- a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs @@ -27,3 +27,9 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] + +[assembly: InternalsVisibleTo("Grpc.Microbenchmarks,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index f775e4c85fb..89597e139ec 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -11,6 +11,7 @@ + diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs new file mode 100644 index 00000000000..cbb4091122b --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Text; +using BenchmarkDotNet.Attributes; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Internal.Tests; + +namespace Grpc.Microbenchmarks +{ + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class Utf8Encode : ISendStatusFromServerCompletionCallback + { + static readonly NativeMethods Native = NativeMethods.Get(); + + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize { get; set; } + + static readonly Dictionary Payloads = new Dictionary { + { 0, Invent(0) }, + { 1, Invent(1) }, + { 4, Invent(4) }, + { 128, Invent(128) }, + { 1024, Invent(1024) }, + }; + + static string Invent(int length) + { + var rand = new Random(Seed: length); + var chars = new char[length]; + for(int i = 0; i < chars.Length; i++) + { + chars[i] = (char)rand.Next(32, 300); + } + return new string(chars); + } + + [GlobalSetup] + public void Setup() + { + Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop"); + metadata = MetadataArraySafeHandle.Create(Metadata.Empty); + call = new FakeNativeCall(); + } + + public void Cleanup() + { + metadata.Dispose(); + metadata = null; + call.Dispose(); + call = null; + } + private INativeCall call; + private MetadataArraySafeHandle metadata; + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public unsafe void Run() + { + string payload = Payloads[PayloadSize]; + var status = new Status(StatusCode.OK, payload); + for (int i = 0; i < Iterations; i++) + { + call.StartSendStatusFromServer(this, status, + metadata, false, null, WriteFlags.NoCompress); + } + } + + void ISendStatusFromServerCompletionCallback.OnSendStatusFromServerCompletion(bool success) { } + } +} From f53d844da9c6d070b52b8e05192fbcb11cea94db Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 17:07:15 +0100 Subject: [PATCH 519/676] attempt to fix the utf-8 encode benchmark; not currently working --- plugins.vcxproj.filters | 17 +++++++ .../Properties/AssemblyInfo.cs | 6 --- .../Grpc.Microbenchmarks.csproj | 1 - src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 47 ++++++++++++++----- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 plugins.vcxproj.filters diff --git a/plugins.vcxproj.filters b/plugins.vcxproj.filters new file mode 100644 index 00000000000..5ce08010501 --- /dev/null +++ b/plugins.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + CMake Rules + + + + + + + + + {870DBD13-69C5-3F27-A253-623E8947E2E7} + + + diff --git a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs index e19010f0509..af264c9be5d 100644 --- a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs @@ -27,9 +27,3 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] - -[assembly: InternalsVisibleTo("Grpc.Microbenchmarks,PublicKey=" + - "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + - "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + - "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + - "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 89597e139ec..f775e4c85fb 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -11,7 +11,6 @@ - diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index cbb4091122b..4061a1a0f02 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -using System.Text; using BenchmarkDotNet.Attributes; using Grpc.Core; using Grpc.Core.Internal; -using Grpc.Core.Internal.Tests; namespace Grpc.Microbenchmarks { @@ -12,9 +10,7 @@ namespace Grpc.Microbenchmarks [MemoryDiagnoser] // allocations public class Utf8Encode : ISendStatusFromServerCompletionCallback { - static readonly NativeMethods Native = NativeMethods.Get(); - - [Params(0, 1, 4, 128, 1024)] + [Params(0)] //, 1, 4, 128, 1024)] public int PayloadSize { get; set; } static readonly Dictionary Payloads = new Dictionary { @@ -36,22 +32,50 @@ namespace Grpc.Microbenchmarks return new string(chars); } + private GrpcEnvironment environment; + [GlobalSetup] public void Setup() { - Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop"); + var native = NativeMethods.Get(); + + // ??? throws ??? + native.grpcsharp_test_override_method(nameof(NativeMethods.grpcsharp_call_send_status_from_server), "nop"); + + environment = GrpcEnvironment.AddRef(); metadata = MetadataArraySafeHandle.Create(Metadata.Empty); - call = new FakeNativeCall(); + var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); + var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); + call = CreateFakeCall(cq); + } + + private static CallSafeHandle CreateFakeCall(CompletionQueueSafeHandle cq) + { + var call = CallSafeHandle.CreateFake(new IntPtr(0xdead), cq); + bool success = false; + while (!success) + { + // avoid calling destroy on a nonexistent grpc_call pointer + call.DangerousAddRef(ref success); + } + return call; } + [GlobalCleanup] public void Cleanup() { - metadata.Dispose(); + metadata?.Dispose(); metadata = null; - call.Dispose(); + call?.Dispose(); call = null; + + if (environment != null) + { + environment = null; + GrpcEnvironment.ReleaseAsync().Wait(); + } } - private INativeCall call; + private CallSafeHandle call; private MetadataArraySafeHandle metadata; const int Iterations = 1000; @@ -62,8 +86,7 @@ namespace Grpc.Microbenchmarks var status = new Status(StatusCode.OK, payload); for (int i = 0; i < Iterations; i++) { - call.StartSendStatusFromServer(this, status, - metadata, false, null, WriteFlags.NoCompress); + call.StartSendStatusFromServer(this, status, metadata, false, null, WriteFlags.NoCompress); } } From e4411e03e65a7f69acc48b22403f6453c37e207e Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 17:11:26 +0100 Subject: [PATCH 520/676] added by mistake --- plugins.vcxproj.filters | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 plugins.vcxproj.filters diff --git a/plugins.vcxproj.filters b/plugins.vcxproj.filters deleted file mode 100644 index 5ce08010501..00000000000 --- a/plugins.vcxproj.filters +++ /dev/null @@ -1,17 +0,0 @@ - - - - - CMake Rules - - - - - - - - - {870DBD13-69C5-3F27-A253-623E8947E2E7} - - - From 0a1147b58c17de641082bbb58859a3b21fcbd34d Mon Sep 17 00:00:00 2001 From: mgravell Date: Mon, 1 Jul 2019 17:28:47 +0100 Subject: [PATCH 521/676] found another way to nop the native-call --- src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index 4061a1a0f02..0c9370679a4 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -39,8 +39,9 @@ namespace Grpc.Microbenchmarks { var native = NativeMethods.Get(); - // ??? throws ??? - native.grpcsharp_test_override_method(nameof(NativeMethods.grpcsharp_call_send_status_from_server), "nop"); + // nop the native-call via reflection + NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => CallError.OK; + native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); environment = GrpcEnvironment.AddRef(); metadata = MetadataArraySafeHandle.Create(Metadata.Empty); From 464f558a456f8dd43609df066722cc5f0a0257bc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 10:12:23 -0700 Subject: [PATCH 522/676] Increase the control message size --- src/core/lib/iomgr/tcp_posix.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 889272f6299..0a2ef767598 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -435,7 +435,9 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; - char cmsgbuf[24 /*CMSG_SPACE(sizeof(int))*/]; + char cmsgbuf + [128 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int))*/ + ]; ssize_t read_bytes; size_t total_read_bytes = 0; From 1c354e7c1f35c969a96bbdf420b6cc2884b712ba Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Mon, 1 Jul 2019 10:38:23 -0700 Subject: [PATCH 523/676] Move grpc async, callback and sync implementation to grpc_impl namespace --- BUILD | 10 + BUILD.gn | 10 + CMakeLists.txt | 40 + Makefile | 40 + build.yaml | 10 + gRPC-C++.podspec | 10 + include/grpcpp/channel_impl.h | 13 +- include/grpcpp/generic/generic_stub_impl.h | 41 +- .../impl/codegen/async_generic_service.h | 28 +- include/grpcpp/impl/codegen/async_stream.h | 1102 +-------------- .../grpcpp/impl/codegen/async_stream_impl.h | 1134 ++++++++++++++++ .../grpcpp/impl/codegen/async_unary_call.h | 291 +--- .../impl/codegen/async_unary_call_impl.h | 315 +++++ include/grpcpp/impl/codegen/byte_buffer.h | 19 +- include/grpcpp/impl/codegen/call_op_set.h | 2 +- .../grpcpp/impl/codegen/channel_interface.h | 47 +- include/grpcpp/impl/codegen/client_callback.h | 1003 +------------- .../impl/codegen/client_callback_impl.h | 1067 +++++++++++++++ .../grpcpp/impl/codegen/client_context_impl.h | 52 +- .../grpcpp/impl/codegen/client_unary_call.h | 4 +- .../impl/codegen/completion_queue_impl.h | 17 +- include/grpcpp/impl/codegen/server_callback.h | 1133 +--------------- .../impl/codegen/server_callback_impl.h | 1186 +++++++++++++++++ .../grpcpp/impl/codegen/server_context_impl.h | 54 +- include/grpcpp/impl/codegen/service_type.h | 20 +- include/grpcpp/impl/codegen/sync_stream.h | 914 +------------ .../grpcpp/impl/codegen/sync_stream_impl.h | 944 +++++++++++++ include/grpcpp/support/async_stream_impl.h | 24 + .../grpcpp/support/async_unary_call_impl.h | 24 + include/grpcpp/support/client_callback_impl.h | 24 + include/grpcpp/support/server_callback_impl.h | 24 + include/grpcpp/support/sync_stream_impl.h | 24 + src/compiler/cpp_generator.cc | 121 +- src/cpp/client/generic_stub.cc | 30 +- src/cpp/server/async_generic_service.cc | 4 +- .../health/default_health_check_service.h | 1 + src/cpp/server/server_builder.cc | 15 +- src/cpp/server/server_context.cc | 11 +- test/cpp/codegen/compiler_test_golden | 37 +- tools/doxygen/Doxyfile.c++ | 10 + tools/doxygen/Doxyfile.c++.internal | 10 + .../generated/sources_and_headers.json | 20 + 42 files changed, 5258 insertions(+), 4627 deletions(-) create mode 100644 include/grpcpp/impl/codegen/async_stream_impl.h create mode 100644 include/grpcpp/impl/codegen/async_unary_call_impl.h create mode 100644 include/grpcpp/impl/codegen/client_callback_impl.h create mode 100644 include/grpcpp/impl/codegen/server_callback_impl.h create mode 100644 include/grpcpp/impl/codegen/sync_stream_impl.h create mode 100644 include/grpcpp/support/async_stream_impl.h create mode 100644 include/grpcpp/support/async_unary_call_impl.h create mode 100644 include/grpcpp/support/client_callback_impl.h create mode 100644 include/grpcpp/support/server_callback_impl.h create mode 100644 include/grpcpp/support/sync_stream_impl.h diff --git a/BUILD b/BUILD index 87d3b978358..b9a47e6e776 100644 --- a/BUILD +++ b/BUILD @@ -268,11 +268,14 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -280,6 +283,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -287,6 +291,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", ] @@ -2155,7 +2160,9 @@ grpc_cc_library( "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -2164,6 +2171,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -2186,6 +2194,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -2197,6 +2206,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h", ], deps = [ diff --git a/BUILD.gn b/BUILD.gn index fc9fa8dc3d0..05e4da5561f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1045,7 +1045,9 @@ config("grpc_config") { "include/grpcpp/impl/client_unary_call.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -1054,6 +1056,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -1082,6 +1085,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -1094,6 +1098,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h", "include/grpcpp/impl/grpc_library.h", "include/grpcpp/impl/method_handler_impl.h", @@ -1123,11 +1128,14 @@ config("grpc_config") { "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -1135,6 +1143,7 @@ config("grpc_config") { "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -1142,6 +1151,7 @@ config("grpc_config") { "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/core/ext/transport/inproc/inproc_transport.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 713fc16028f..c47684addac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3205,11 +3205,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -3217,6 +3220,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -3224,6 +3228,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -3309,7 +3314,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -3318,6 +3325,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -3340,6 +3348,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -3351,6 +3360,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h @@ -3827,11 +3837,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -3839,6 +3852,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -3846,6 +3860,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -3931,7 +3946,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -3940,6 +3957,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -3962,6 +3980,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -3973,6 +3992,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h include/grpc/census.h @@ -4368,7 +4388,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4377,6 +4399,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4399,6 +4422,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4410,6 +4434,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpc/impl/codegen/byte_buffer.h include/grpc/impl/codegen/byte_buffer_reader.h @@ -4569,7 +4594,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4578,6 +4605,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4600,6 +4628,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4611,6 +4640,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpc/impl/codegen/byte_buffer.h include/grpc/impl/codegen/byte_buffer_reader.h @@ -4827,11 +4857,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -4839,6 +4872,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -4846,6 +4880,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -4931,7 +4966,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4940,6 +4977,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4962,6 +5000,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4973,6 +5012,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h ) diff --git a/Makefile b/Makefile index 15d4ede0670..44c428afdb1 100644 --- a/Makefile +++ b/Makefile @@ -5582,11 +5582,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -5594,6 +5597,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -5601,6 +5605,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -5686,7 +5691,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -5695,6 +5702,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -5717,6 +5725,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -5728,6 +5737,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ @@ -6212,11 +6222,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -6224,6 +6237,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -6231,6 +6245,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -6316,7 +6331,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6325,6 +6342,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6347,6 +6365,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6358,6 +6377,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ include/grpc/census.h \ @@ -6725,7 +6745,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6734,6 +6756,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6756,6 +6779,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6767,6 +6791,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -6897,7 +6922,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6906,6 +6933,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6928,6 +6956,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6939,6 +6968,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -7161,11 +7191,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -7173,6 +7206,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -7180,6 +7214,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -7265,7 +7300,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -7274,6 +7311,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -7296,6 +7334,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -7307,6 +7346,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ diff --git a/build.yaml b/build.yaml index d342e88d24c..8e769ed9923 100644 --- a/build.yaml +++ b/build.yaml @@ -1250,7 +1250,9 @@ filegroups: - include/grpc++/impl/codegen/time.h - include/grpcpp/impl/codegen/async_generic_service.h - include/grpcpp/impl/codegen/async_stream.h + - include/grpcpp/impl/codegen/async_stream_impl.h - include/grpcpp/impl/codegen/async_unary_call.h + - include/grpcpp/impl/codegen/async_unary_call_impl.h - include/grpcpp/impl/codegen/byte_buffer.h - include/grpcpp/impl/codegen/call.h - include/grpcpp/impl/codegen/call_hook.h @@ -1259,6 +1261,7 @@ filegroups: - include/grpcpp/impl/codegen/callback_common.h - include/grpcpp/impl/codegen/channel_interface.h - include/grpcpp/impl/codegen/client_callback.h + - include/grpcpp/impl/codegen/client_callback_impl.h - include/grpcpp/impl/codegen/client_context.h - include/grpcpp/impl/codegen/client_context_impl.h - include/grpcpp/impl/codegen/client_interceptor.h @@ -1281,6 +1284,7 @@ filegroups: - include/grpcpp/impl/codegen/security/auth_context.h - include/grpcpp/impl/codegen/serialization_traits.h - include/grpcpp/impl/codegen/server_callback.h + - include/grpcpp/impl/codegen/server_callback_impl.h - include/grpcpp/impl/codegen/server_context.h - include/grpcpp/impl/codegen/server_context_impl.h - include/grpcpp/impl/codegen/server_interceptor.h @@ -1292,6 +1296,7 @@ filegroups: - include/grpcpp/impl/codegen/string_ref.h - include/grpcpp/impl/codegen/stub_options.h - include/grpcpp/impl/codegen/sync_stream.h + - include/grpcpp/impl/codegen/sync_stream_impl.h - include/grpcpp/impl/codegen/time.h uses: - grpc_codegen @@ -1410,11 +1415,14 @@ filegroups: - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h - include/grpcpp/support/async_stream.h + - include/grpcpp/support/async_stream_impl.h - include/grpcpp/support/async_unary_call.h + - include/grpcpp/support/async_unary_call_impl.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h - include/grpcpp/support/channel_arguments_impl.h - include/grpcpp/support/client_callback.h + - include/grpcpp/support/client_callback_impl.h - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h - include/grpcpp/support/interceptor.h @@ -1422,6 +1430,7 @@ filegroups: - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h - include/grpcpp/support/server_callback.h + - include/grpcpp/support/server_callback_impl.h - include/grpcpp/support/server_interceptor.h - include/grpcpp/support/slice.h - include/grpcpp/support/status.h @@ -1429,6 +1438,7 @@ filegroups: - include/grpcpp/support/string_ref.h - include/grpcpp/support/stub_options.h - include/grpcpp/support/sync_stream.h + - include/grpcpp/support/sync_stream_impl.h - include/grpcpp/support/time.h - include/grpcpp/support/validate_service_config.h headers: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 6fc97c6135e..ad396396843 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -129,11 +129,14 @@ Pod::Spec.new do |s| 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', 'include/grpcpp/support/async_stream.h', + 'include/grpcpp/support/async_stream_impl.h', 'include/grpcpp/support/async_unary_call.h', + 'include/grpcpp/support/async_unary_call_impl.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', 'include/grpcpp/support/channel_arguments_impl.h', 'include/grpcpp/support/client_callback.h', + 'include/grpcpp/support/client_callback_impl.h', 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', 'include/grpcpp/support/interceptor.h', @@ -141,6 +144,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', 'include/grpcpp/support/server_callback.h', + 'include/grpcpp/support/server_callback_impl.h', 'include/grpcpp/support/server_interceptor.h', 'include/grpcpp/support/slice.h', 'include/grpcpp/support/status.h', @@ -148,11 +152,14 @@ Pod::Spec.new do |s| 'include/grpcpp/support/string_ref.h', 'include/grpcpp/support/stub_options.h', 'include/grpcpp/support/sync_stream.h', + 'include/grpcpp/support/sync_stream_impl.h', 'include/grpcpp/support/time.h', 'include/grpcpp/support/validate_service_config.h', 'include/grpcpp/impl/codegen/async_generic_service.h', 'include/grpcpp/impl/codegen/async_stream.h', + 'include/grpcpp/impl/codegen/async_stream_impl.h', 'include/grpcpp/impl/codegen/async_unary_call.h', + 'include/grpcpp/impl/codegen/async_unary_call_impl.h', 'include/grpcpp/impl/codegen/byte_buffer.h', 'include/grpcpp/impl/codegen/call.h', 'include/grpcpp/impl/codegen/call_hook.h', @@ -161,6 +168,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/callback_common.h', 'include/grpcpp/impl/codegen/channel_interface.h', 'include/grpcpp/impl/codegen/client_callback.h', + 'include/grpcpp/impl/codegen/client_callback_impl.h', 'include/grpcpp/impl/codegen/client_context.h', 'include/grpcpp/impl/codegen/client_context_impl.h', 'include/grpcpp/impl/codegen/client_interceptor.h', @@ -183,6 +191,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/security/auth_context.h', 'include/grpcpp/impl/codegen/serialization_traits.h', 'include/grpcpp/impl/codegen/server_callback.h', + 'include/grpcpp/impl/codegen/server_callback_impl.h', 'include/grpcpp/impl/codegen/server_context.h', 'include/grpcpp/impl/codegen/server_context_impl.h', 'include/grpcpp/impl/codegen/server_interceptor.h', @@ -194,6 +203,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/string_ref.h', 'include/grpcpp/impl/codegen/stub_options.h', 'include/grpcpp/impl/codegen/sync_stream.h', + 'include/grpcpp/impl/codegen/sync_stream_impl.h', 'include/grpcpp/impl/codegen/time.h', 'include/grpcpp/impl/codegen/sync.h' end diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index a7eee2b8981..9ff3118645f 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -86,22 +86,23 @@ class Channel final : public ::grpc::ChannelInterface, ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, - ::grpc::CompletionQueue* cq) override; + ::grpc_impl::CompletionQueue* cq) override; void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, ::grpc::internal::Call* call) override; void* RegisterMethod(const char* method) override; void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc_impl::CompletionQueue* cq, + void* tag) override; bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; - ::grpc::CompletionQueue* CallbackCQ() override; + ::grpc_impl::CompletionQueue* CallbackCQ() override; ::grpc::internal::Call CreateCallInternal( const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq, + ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) override; const grpc::string host_; @@ -114,7 +115,7 @@ class Channel final : public ::grpc::ChannelInterface, // with this channel (if any). It is set on the first call to CallbackCQ(). // It is _not owned_ by the channel; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). - ::grpc::CompletionQueue* callback_cq_ = nullptr; + ::grpc_impl::CompletionQueue* callback_cq_ = nullptr; std::vector< std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index fdbc0d0a272..e670fcaa654 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -22,17 +22,20 @@ #include #include -#include -#include +#include +#include #include -#include +#include #include +#include + namespace grpc { -typedef ClientAsyncReaderWriter +typedef ::grpc_impl::ClientAsyncReaderWriter GenericClientAsyncReaderWriter; -typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; +typedef ::grpc_impl::ClientAsyncResponseReader + GenericClientAsyncResponseReader; } // namespace grpc namespace grpc_impl { class CompletionQueue; @@ -50,15 +53,15 @@ class GenericStub final { /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr PrepareCall( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq); + CompletionQueue* cq); /// Setup a unary call to a named method \a method using \a context, and don't /// start it. Let it be started explicitly with StartCall. /// The return value only indicates whether or not registration of the call /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr PrepareUnaryCall( - grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer& request, grpc::CompletionQueue* cq); + grpc_impl::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer& request, CompletionQueue* cq); /// DEPRECATED for multi-threaded use /// Begin a call to a named method \a method using \a context. @@ -67,8 +70,8 @@ class GenericStub final { /// The return value only indicates whether or not registration of the call /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr Call( - grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq, void* tag); + grpc_impl::ClientContext* context, const grpc::string& method, + CompletionQueue* cq, void* tag); /// NOTE: class experimental_type is not part of the public API of this class /// TODO(vjpai): Move these contents to the public API of GenericStub when @@ -79,23 +82,25 @@ class GenericStub final { /// Setup and start a unary call to a named method \a method using /// \a context and specifying the \a request and \a response buffers. - void UnaryCall(grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + void UnaryCall(grpc_impl::ClientContext* context, + const grpc::string& method, const grpc::ByteBuffer* request, + grpc::ByteBuffer* response, std::function on_completion); /// Setup and start a unary call to a named method \a method using /// \a context and specifying the \a request and \a response buffers. - void UnaryCall(grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer* request, grpc::ByteBuffer* response, - grpc::experimental::ClientUnaryReactor* reactor); + void UnaryCall(grpc_impl::ClientContext* context, + const grpc::string& method, const grpc::ByteBuffer* request, + grpc::ByteBuffer* response, + grpc_impl::experimental::ClientUnaryReactor* reactor); /// Setup a call to a named method \a method using \a context and tied to /// \a reactor . Like any other bidi streaming RPC, it will not be activated /// until StartCall is invoked on its reactor. void PrepareBidiStreamingCall( - grpc::ClientContext* context, const grpc::string& method, - grpc::experimental::ClientBidiReactor* reactor); + grpc_impl::ClientContext* context, const grpc::string& method, + grpc_impl::experimental::ClientBidiReactor* reactor); private: GenericStub* stub_; diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index d8e6f49b2f3..7c720ce3c23 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -19,19 +19,21 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H #define GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H -#include +#include #include -#include +#include struct grpc_server; namespace grpc { -typedef ServerAsyncReaderWriter +typedef ::grpc_impl::ServerAsyncReaderWriter GenericServerAsyncReaderWriter; -typedef ServerAsyncResponseWriter GenericServerAsyncResponseWriter; -typedef ServerAsyncReader GenericServerAsyncReader; -typedef ServerAsyncWriter GenericServerAsyncWriter; +typedef ::grpc_impl::ServerAsyncResponseWriter + GenericServerAsyncResponseWriter; +typedef ::grpc_impl::ServerAsyncReader + GenericServerAsyncReader; +typedef ::grpc_impl::ServerAsyncWriter GenericServerAsyncWriter; class GenericServerContext final : public ::grpc_impl::ServerContext { public: @@ -75,8 +77,9 @@ class AsyncGenericService final { void RequestCall(GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag); private: friend class grpc_impl::Server; @@ -91,7 +94,8 @@ namespace experimental { /// GenericServerContext rather than a ServerContext. All other reaction and /// operation initiation APIs are the same as ServerBidiReactor. class ServerGenericBidiReactor - : public ServerBidiReactor { + : public ::grpc_impl::experimental::ServerBidiReactor { public: /// Similar to ServerBidiReactor::OnStarted except for argument type. /// @@ -137,8 +141,10 @@ class CallbackGenericService { private: friend class ::grpc_impl::Server; - internal::CallbackBidiHandler* Handler() { - return new internal::CallbackBidiHandler( + ::grpc_impl::internal::CallbackBidiHandler* + Handler() { + return new ::grpc_impl::internal::CallbackBidiHandler( [this] { return CreateReactor(); }); } diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index 417dceb587f..14dfe67962e 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -19,1117 +19,47 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H #define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -namespace internal { -/// Common interface for all client side asynchronous streaming. -class ClientAsyncStreamingInterface { - public: - virtual ~ClientAsyncStreamingInterface() {} - - /// Start the call that was set up by the constructor, but only if the - /// constructor was invoked through the "Prepare" API which doesn't actually - /// start the call - virtual void StartCall(void* tag) = 0; - - /// Request notification of the reading of the initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a AsyncReaderInterface::Read method. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Indicate that the stream is to be finished and request notification for - /// when the call has been ended. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when both: - /// * the client side has no more message to send - /// (this can be declared implicitly by calling this method, or - /// explicitly through an earlier call to the WritesDone method - /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or - /// \a ClientAsyncReaderWriterInterface::WritesDone). - /// * there are no more messages to be received from the server (this can - /// be known implicitly by the calling code, or explicitly from an - /// earlier call to \a AsyncReaderInterface::Read that yielded a failed - /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). - /// - /// The tag will be returned when either: - /// - all incoming messages have been read and the server has returned - /// a status. - /// - the server has returned a non-OK status. - /// - the call failed for some reason and the library generated a - /// status. - /// - /// Note that implementations of this method attempt to receive initial - /// metadata from the server if initial metadata hasn't yet been received. - /// - /// \param[in] tag Tag identifying this request. - /// \param[out] status To be updated with the operation status. - virtual void Finish(Status* status, void* tag) = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. -template -class AsyncReaderInterface { - public: - virtual ~AsyncReaderInterface() {} - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a AsyncReaderInterface::Read on the same stream since reads - /// on the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - /// - /// Side effect: note that this method attempt to receive initial metadata for - /// a stream if it hasn't yet been received. - virtual void Read(R* msg, void* tag) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class AsyncWriterInterface { - public: - virtual ~AsyncWriterInterface() {} - - /// Request the writing of \a msg with identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// This is thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, void* tag) = 0; - - /// Request the writing of \a msg using WriteOptions \a options with - /// identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// WriteOptions \a options is used to set the write options of this message. - /// This is thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, WriteOptions options, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with the writing - /// of trailing metadata, using WriteOptions \a options with - /// identifying tag \a tag. - /// - /// For client, WriteLast is equivalent of performing Write and - /// WritesDone in a single step. - /// For server, WriteLast buffers the \a msg. The writing of \a msg is held - /// until Finish is called, where \a msg and trailing metadata are coalesced - /// and write is initiated. Note that WriteLast can only buffer \a msg up to - /// the flow control window size. If \a msg size is larger than the window - /// size, it will be sent on wire without buffering. - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] tag The tag identifying the operation. - void WriteLast(const W& msg, WriteOptions options, void* tag) { - Write(msg, options.set_last_message(), tag); - } -}; - -} // namespace internal - template -class ClientAsyncReaderInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncReaderInterface {}; +using ClientAsyncReaderInterface = ::grpc_impl::ClientAsyncReaderInterface; -namespace internal { template -class ClientAsyncReaderFactory { - public: - /// Create a stream object. - /// Write the first request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started and - /// \a request has been written out. If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template - static ClientAsyncReader* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const W& request, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReader))) - ClientAsyncReader(call, context, request, start, tag); - } -}; -} // namespace internal - -/// Async client-side API for doing server-streaming RPCs, -/// where the incoming message stream coming from the server has -/// messages of type \a R. -template -class ClientAsyncReader final : public ClientAsyncReaderInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncReader)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata - /// method for semantics. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, - /// the \a ClientContext associated with this call is updated, and the - /// calling code can access the received metadata through the - /// \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - assert(started_); - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata received from the server. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } +using ClientAsyncReader = ::grpc_impl::ClientAsyncReader; - private: - friend class internal::ClientAsyncReaderFactory; - template - ClientAsyncReader(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, const W& request, - bool start, void* tag) - : context_(context), call_(call), started_(start) { - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); - init_ops_.ClientSendClose(); - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - init_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - init_ops_.set_output_tag(tag); - call_.PerformOps(&init_ops_); - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - init_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; - -/// Common interface for client side asynchronous writing. template -class ClientAsyncWriterInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncWriterInterface { - public: - /// Signal the client is done with the writes (half-close the client stream). - /// Thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; +using ClientAsyncWriterInterface = ::grpc_impl::ClientAsyncWriterInterface; -namespace internal { template -class ClientAsyncWriterFactory { - public: - /// Create a stream object. - /// Start the RPC if \a start is set - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, \a tag must be nullptr and the actual call - /// must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - /// \a response will be filled in with the single expected response - /// message from the server upon a successful call to the \a Finish - /// method of this instance. - template - static ClientAsyncWriter* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - R* response, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncWriter))) - ClientAsyncWriter(call, context, response, start, tag); - } -}; -} // namespace internal - -/// Async API on the client side for doing client-streaming RPCs, -/// where the outgoing message stream going to the server contains -/// messages of type \a W. -template -class ClientAsyncWriter final : public ClientAsyncWriterInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncWriter)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for - /// semantics. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, the \a ClientContext - /// associated with this call is updated, and the calling code can access - /// the received metadata through the \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } +using ClientAsyncWriter = ::grpc_impl::ClientAsyncWriter; - void WritesDone(void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - write_ops_.ClientSendClose(); - call_.PerformOps(&write_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata received from the server. - /// - attempts to fill in the \a response parameter passed to this class's - /// constructor with the server's response message. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class internal::ClientAsyncWriterFactory; - template - ClientAsyncWriter(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, R* response, - bool start, void* tag) - : context_(context), call_(call), started_(start) { - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - // if corked bit is set in context, we just keep the initial metadata - // buffered up to coalesce with later message send. No op is performed. - if (!context_->initial_metadata_corked_) { - write_ops_.set_output_tag(tag); - call_.PerformOps(&write_ops_); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpGenericRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; - -/// Async client-side interface for bi-directional streaming, -/// where the client-to-server message stream has messages of type \a W, -/// and the server-to-client message stream has messages of type \a R. template -class ClientAsyncReaderWriterInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncWriterInterface, - public internal::AsyncReaderInterface { - public: - /// Signal the client is done with the writes (half-close the client stream). - /// Thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; +using ClientAsyncReaderWriterInterface = + ::grpc_impl::ClientAsyncReaderWriterInterface; -namespace internal { template -class ClientAsyncReaderWriterFactory { - public: - /// Create a stream object. - /// Start the RPC request if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent). If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - static ClientAsyncReaderWriter* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReaderWriter))) - ClientAsyncReaderWriter(call, context, start, tag); - } -}; -} // namespace internal - -/// Async client-side interface for bi-directional streaming, -/// where the outgoing message stream going to the server -/// has messages of type \a W, and the incoming message stream coming -/// from the server has messages of type \a R. -template -class ClientAsyncReaderWriter final - : public ClientAsyncReaderWriterInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncReaderWriter)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method - /// for semantics of this method. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, the \a ClientContext - /// is updated with it, and then the receiving initial metadata can - /// be accessed through this \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - assert(started_); - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - write_ops_.ClientSendClose(); - call_.PerformOps(&write_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// Side effect - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, bool start, - void* tag) - : context_(context), call_(call), started_(start) { - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - // if corked bit is set in context, we just keep the initial metadata - // buffered up to coalesce with later message send. No op is performed. - if (!context_->initial_metadata_corked_) { - write_ops_.set_output_tag(tag); - call_.PerformOps(&write_ops_); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; +using ClientAsyncReaderWriter = ::grpc_impl::ClientAsyncReaderWriter; template -class ServerAsyncReaderInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncReaderInterface { - public: - /// Indicate that the stream is to be finished with a certain status code - /// and also send out \a msg response to the client. - /// Request notification for when the server has sent the response and the - /// appropriate signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous - /// \a AsyncReaderInterface::Read operation with a non-ok result, - /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if - /// some failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it - /// is safe to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - /// \param[in] msg To be sent to the client as the response for this call. - virtual void Finish(const W& msg, const Status& status, void* tag) = 0; - - /// Indicate that the stream is to be finished with a certain - /// non-OK status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// This call is meant to end the call with some error, and can be called at - /// any point that the server would like to "fail" the call (though note - /// this shouldn't be called concurrently with any other "sending" call, like - /// \a AsyncWriterInterface::Write). - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), and status, or if some failure occurred - /// when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once FinishWithError returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - /// - Note: \a status must have a non-OK code. - virtual void FinishWithError(const Status& status, void* tag) = 0; -}; +using ServerAsyncReaderInterface = + ::grpc_impl::ServerAsyncReaderInterface; -/// Async server-side API for doing client-streaming RPCs, -/// where the incoming message stream from the client has messages of type \a R, -/// and the single response message sent from the server is type \a W. template -class ServerAsyncReader final : public ServerAsyncReaderInterface { - public: - explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - /// See the \a ServerAsyncReaderInterface.Read method for semantics - /// - /// Side effect: - /// - also sends initial metadata if not alreay sent. - /// - uses the \a ServerContext associated with this call to send possible - /// initial and trailing metadata. - /// - /// Note: \a msg is not sent if \a status has a non-OK code. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once Finish returns. - void Finish(const W& msg, const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(msg)); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_ops_); - } - - /// See the \a ServerAsyncReaderInterface.Read method for semantics - /// - /// Side effect: - /// - also sends initial metadata if not alreay sent. - /// - uses the \a ServerContext associated with this call to send possible - /// initial and trailing metadata. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once FinishWithError returns. - void FinishWithError(const Status& status, void* tag) override { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; +using ServerAsyncReader = ::grpc_impl::ServerAsyncReader; template -class ServerAsyncWriterInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncWriterInterface { - public: - /// Indicate that the stream is to be finished with a certain status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when either: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous \a - /// AsyncReaderInterface::Read operation with a non-ok - /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'. - /// * it is desired to end the call early with some non-OK status code. - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if - /// some failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - virtual void Finish(const Status& status, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with trailing metadata which - /// contains \a status, using WriteOptions options with - /// identifying tag \a tag. - /// - /// WriteAndFinish is equivalent of performing WriteLast and Finish - /// in a single step. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] status The Status that server returns to client. - /// \param[in] tag The tag identifying the operation. - virtual void WriteAndFinish(const W& msg, WriteOptions options, - const Status& status, void* tag) = 0; -}; +using ServerAsyncWriterInterface = ::grpc_impl::ServerAsyncWriterInterface; -/// Async server-side API for doing server streaming RPCs, -/// where the outgoing message stream from the server has messages of type \a W. template -class ServerAsyncWriter final : public ServerAsyncWriterInterface { - public: - explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } +using ServerAsyncWriter = ::grpc_impl::ServerAsyncWriter; - void Write(const W& msg, WriteOptions options, void* tag) override { - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used - /// for sending trailing (and initial) metadata to the client. - /// - /// Note: \a status must have an OK code. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, - void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - options.set_buffer_hint(); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncWriterInterface.Finish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used for sending - /// trailing (and initial if not already sent) metadata to the client. - /// - /// Note: there are no restrictions are the code of - /// \a status,it may be non-OK - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - void Finish(const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&finish_ops_); - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - template - void EnsureInitialMetadataSent(T* ops) { - if (!ctx_->sent_initial_metadata_) { - ops->SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops->set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; - -/// Server-side interface for asynchronous bi-directional streaming. template -class ServerAsyncReaderWriterInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncWriterInterface, - public internal::AsyncReaderInterface { - public: - /// Indicate that the stream is to be finished with a certain status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when either: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous \a - /// AsyncReaderInterface::Read operation - /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' - /// with 'false'. - /// * it is desired to end the call early with some non-OK status code. - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if some - /// failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - virtual void Finish(const Status& status, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with trailing metadata which - /// contains \a status, using WriteOptions options with - /// identifying tag \a tag. - /// - /// WriteAndFinish is equivalent of performing WriteLast and Finish in a - /// single step. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] status The Status that server returns to client. - /// \param[in] tag The tag identifying the operation. - virtual void WriteAndFinish(const W& msg, WriteOptions options, - const Status& status, void* tag) = 0; -}; +using ServerAsyncReaderWriterInterface = + ::grpc_impl::ServerAsyncReaderWriterInterface; -/// Async server-side API for doing bidirectional streaming RPCs, -/// where the incoming message stream coming from the client has messages of -/// type \a R, and the outgoing message stream coming from the server has -/// messages of type \a W. template -class ServerAsyncReaderWriter final - : public ServerAsyncReaderWriterInterface { - public: - explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - EnsureInitialMetadataSent(&write_ops_); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish - /// method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used - /// for sending trailing (and initial) metadata to the client. - /// - /// Note: \a status must have an OK code. - // - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, - void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - options.set_buffer_hint(); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used for sending - /// trailing (and initial if not already sent) metadata to the client. - /// - /// Note: there are no restrictions are the code of \a status, - /// it may be non-OK - // - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - void Finish(const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&finish_ops_); - - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class ::grpc_impl::Server; - - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - template - void EnsureInitialMetadataSent(T* ops) { - if (!ctx_->sent_initial_metadata_) { - ops->SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops->set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; - +using ServerAsyncReaderWriter = ::grpc_impl::ServerAsyncReaderWriter; } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H diff --git a/include/grpcpp/impl/codegen/async_stream_impl.h b/include/grpcpp/impl/codegen/async_stream_impl.h new file mode 100644 index 00000000000..633a3d5dd00 --- /dev/null +++ b/include/grpcpp/impl/codegen/async_stream_impl.h @@ -0,0 +1,1134 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H +#define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H + +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +namespace internal { +/// Common interface for all client side asynchronous streaming. +class ClientAsyncStreamingInterface { + public: + virtual ~ClientAsyncStreamingInterface() {} + + /// Start the call that was set up by the constructor, but only if the + /// constructor was invoked through the "Prepare" API which doesn't actually + /// start the call + virtual void StartCall(void* tag) = 0; + + /// Request notification of the reading of the initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a AsyncReaderInterface::Read method. + /// + /// \param[in] tag Tag identifying this request. + virtual void ReadInitialMetadata(void* tag) = 0; + + /// Indicate that the stream is to be finished and request notification for + /// when the call has been ended. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when both: + /// * the client side has no more message to send + /// (this can be declared implicitly by calling this method, or + /// explicitly through an earlier call to the WritesDone method + /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or + /// \a ClientAsyncReaderWriterInterface::WritesDone). + /// * there are no more messages to be received from the server (this can + /// be known implicitly by the calling code, or explicitly from an + /// earlier call to \a AsyncReaderInterface::Read that yielded a failed + /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). + /// + /// The tag will be returned when either: + /// - all incoming messages have been read and the server has returned + /// a status. + /// - the server has returned a non-OK status. + /// - the call failed for some reason and the library generated a + /// status. + /// + /// Note that implementations of this method attempt to receive initial + /// metadata from the server if initial metadata hasn't yet been received. + /// + /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. + virtual void Finish(::grpc::Status* status, void* tag) = 0; +}; + +/// An interface that yields a sequence of messages of type \a R. +template +class AsyncReaderInterface { + public: + virtual ~AsyncReaderInterface() {} + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a AsyncReaderInterface::Read on the same stream since reads + /// on the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + /// + /// Side effect: note that this method attempt to receive initial metadata for + /// a stream if it hasn't yet been received. + virtual void Read(R* msg, void* tag) = 0; +}; + +/// An interface that can be fed a sequence of messages of type \a W. +template +class AsyncWriterInterface { + public: + virtual ~AsyncWriterInterface() {} + + /// Request the writing of \a msg with identifying tag \a tag. + /// + /// Only one write may be outstanding at any given time. This means that + /// after calling Write, one must wait to receive \a tag from the completion + /// queue BEFORE calling Write again. + /// This is thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] tag The tag identifying the operation. + virtual void Write(const W& msg, void* tag) = 0; + + /// Request the writing of \a msg using WriteOptions \a options with + /// identifying tag \a tag. + /// + /// Only one write may be outstanding at any given time. This means that + /// after calling Write, one must wait to receive \a tag from the completion + /// queue BEFORE calling Write again. + /// WriteOptions \a options is used to set the write options of this message. + /// This is thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] tag The tag identifying the operation. + virtual void Write(const W& msg, ::grpc::WriteOptions options, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with the writing + /// of trailing metadata, using WriteOptions \a options with + /// identifying tag \a tag. + /// + /// For client, WriteLast is equivalent of performing Write and + /// WritesDone in a single step. + /// For server, WriteLast buffers the \a msg. The writing of \a msg is held + /// until Finish is called, where \a msg and trailing metadata are coalesced + /// and write is initiated. Note that WriteLast can only buffer \a msg up to + /// the flow control window size. If \a msg size is larger than the window + /// size, it will be sent on wire without buffering. + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] tag The tag identifying the operation. + void WriteLast(const W& msg, ::grpc::WriteOptions options, void* tag) { + Write(msg, options.set_last_message(), tag); + } +}; + +} // namespace internal + +template +class ClientAsyncReaderInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncReaderInterface {}; + +namespace internal { +template +class ClientAsyncReaderFactory { + public: + /// Create a stream object. + /// Write the first request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started and + /// \a request has been written out. If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template + static ClientAsyncReader* Create(::grpc::ChannelInterface* channel, + ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const W& request, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReader))) + ClientAsyncReader(call, context, request, start, tag); + } +}; +} // namespace internal + +/// Async client-side API for doing server-streaming RPCs, +/// where the incoming message stream coming from the server has +/// messages of type \a R. +template +class ClientAsyncReader final : public ClientAsyncReaderInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncReader)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata + /// method for semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, + /// the \a ClientContext associated with this call is updated, and the + /// calling code can access the received metadata through the + /// \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + assert(started_); + read_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + read_ops_.RecvInitialMetadata(context_); + } + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncReaderFactory; + template + ClientAsyncReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, + bool start, void* tag) + : context_(context), call_(call), started_(start) { + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); + init_ops_.ClientSendClose(); + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + init_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + init_ops_.set_output_tag(tag); + call_.PerformOps(&init_ops_); + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + init_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +/// Common interface for client side asynchronous writing. +template +class ClientAsyncWriterInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncWriterInterface { + public: + /// Signal the client is done with the writes (half-close the client stream). + /// Thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// \param[in] tag The tag identifying the operation. + virtual void WritesDone(void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncWriterFactory { + public: + /// Create a stream object. + /// Start the RPC if \a start is set + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, \a tag must be nullptr and the actual call + /// must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + /// \a response will be filled in with the single expected response + /// message from the server upon a successful call to the \a Finish + /// method of this instance. + template + static ClientAsyncWriter* Create(::grpc::ChannelInterface* channel, + ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + R* response, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncWriter))) + ClientAsyncWriter(call, context, response, start, tag); + } +}; +} // namespace internal + +/// Async API on the client side for doing client-streaming RPCs, +/// where the outgoing message stream going to the server contains +/// messages of type \a W. +template +class ClientAsyncWriter final : public ClientAsyncWriterInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncWriter)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for + /// semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, the \a ClientContext + /// associated with this call is updated, and the calling code can access + /// the received metadata through the \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Write(const W& msg, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WritesDone(void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + write_ops_.ClientSendClose(); + call_.PerformOps(&write_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. + /// - attempts to fill in the \a response parameter passed to this class's + /// constructor with the server's response message. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncWriterFactory; + template + ClientAsyncWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, R* response, + bool start, void* tag) + : context_(context), call_(call), started_(start) { + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + // if corked bit is set in context, we just keep the initial metadata + // buffered up to coalesce with later message send. No op is performed. + if (!context_->initial_metadata_corked_) { + write_ops_.set_output_tag(tag); + call_.PerformOps(&write_ops_); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpGenericRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +/// Async client-side interface for bi-directional streaming, +/// where the client-to-server message stream has messages of type \a W, +/// and the server-to-client message stream has messages of type \a R. +template +class ClientAsyncReaderWriterInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncWriterInterface, + public internal::AsyncReaderInterface { + public: + /// Signal the client is done with the writes (half-close the client stream). + /// Thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// \param[in] tag The tag identifying the operation. + virtual void WritesDone(void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncReaderWriterFactory { + public: + /// Create a stream object. + /// Start the RPC request if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent). If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + static ClientAsyncReaderWriter* Create( + ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReaderWriter))) + ClientAsyncReaderWriter(call, context, start, tag); + } +}; +} // namespace internal + +/// Async client-side interface for bi-directional streaming, +/// where the outgoing message stream going to the server +/// has messages of type \a W, and the incoming message stream coming +/// from the server has messages of type \a R. +template +class ClientAsyncReaderWriter final + : public ClientAsyncReaderWriterInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncReaderWriter)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method + /// for semantics of this method. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, the \a ClientContext + /// is updated with it, and then the receiving initial metadata can + /// be accessed through this \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + assert(started_); + read_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + read_ops_.RecvInitialMetadata(context_); + } + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + void Write(const W& msg, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WritesDone(void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + write_ops_.ClientSendClose(); + call_.PerformOps(&write_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// Side effect + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncReaderWriterFactory; + ClientAsyncReaderWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, bool start, + void* tag) + : context_(context), call_(call), started_(start) { + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + // if corked bit is set in context, we just keep the initial metadata + // buffered up to coalesce with later message send. No op is performed. + if (!context_->initial_metadata_corked_) { + write_ops_.set_output_tag(tag); + call_.PerformOps(&write_ops_); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +template +class ServerAsyncReaderInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncReaderInterface { + public: + /// Indicate that the stream is to be finished with a certain status code + /// and also send out \a msg response to the client. + /// Request notification for when the server has sent the response and the + /// appropriate signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous + /// \a AsyncReaderInterface::Read operation with a non-ok result, + /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if + /// some failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it + /// is safe to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// \param[in] msg To be sent to the client as the response for this call. + virtual void Finish(const W& msg, const ::grpc::Status& status, + void* tag) = 0; + + /// Indicate that the stream is to be finished with a certain + /// non-OK status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// This call is meant to end the call with some error, and can be called at + /// any point that the server would like to "fail" the call (though note + /// this shouldn't be called concurrently with any other "sending" call, like + /// \a AsyncWriterInterface::Write). + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), and status, or if some failure occurred + /// when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// - Note: \a status must have a non-OK code. + virtual void FinishWithError(const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing client-streaming RPCs, +/// where the incoming message stream from the client has messages of type \a R, +/// and the single response message sent from the server is type \a W. +template +class ServerAsyncReader final : public ServerAsyncReaderInterface { + public: + explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + read_ops_.set_output_tag(tag); + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. + /// + /// Note: \a msg is not sent if \a status has a non-OK code. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once Finish returns. + void Finish(const W& msg, const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (status.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessage(msg)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + } + call_.PerformOps(&finish_ops_); + } + + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. + void FinishWithError(const ::grpc::Status& status, void* tag) override { + GPR_CODEGEN_ASSERT(!status.ok()); + finish_ops_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +template +class ServerAsyncWriterInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncWriterInterface { + public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a + /// AsyncReaderInterface::Read operation with a non-ok + /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if + /// some failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + virtual void Finish(const ::grpc::Status& status, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with trailing metadata which + /// contains \a status, using WriteOptions options with + /// identifying tag \a tag. + /// + /// WriteAndFinish is equivalent of performing WriteLast and Finish + /// in a single step. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] status The Status that server returns to client. + /// \param[in] tag The tag identifying the operation. + virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing server streaming RPCs, +/// where the outgoing message stream from the server has messages of type \a W. +template +class ServerAsyncWriter final : public ServerAsyncWriterInterface { + public: + explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Write(const W& msg, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + options.set_buffer_hint(); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used for sending + /// trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of + /// \a status,it may be non-OK + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + void Finish(const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&finish_ops_); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + template + void EnsureInitialMetadataSent(T* ops) { + if (!ctx_->sent_initial_metadata_) { + ops->SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops->set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +/// Server-side interface for asynchronous bi-directional streaming. +template +class ServerAsyncReaderWriterInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncWriterInterface, + public internal::AsyncReaderInterface { + public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a + /// AsyncReaderInterface::Read operation + /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' + /// with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if some + /// failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + virtual void Finish(const ::grpc::Status& status, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with trailing metadata which + /// contains \a status, using WriteOptions options with + /// identifying tag \a tag. + /// + /// WriteAndFinish is equivalent of performing WriteLast and Finish in a + /// single step. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] status The Status that server returns to client. + /// \param[in] tag The tag identifying the operation. + virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing bidirectional streaming RPCs, +/// where the incoming message stream coming from the client has messages of +/// type \a R, and the outgoing message stream coming from the server has +/// messages of type \a W. +template +class ServerAsyncReaderWriter final + : public ServerAsyncReaderWriterInterface { + public: + explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + read_ops_.set_output_tag(tag); + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + void Write(const W& msg, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + EnsureInitialMetadataSent(&write_ops_); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish + /// method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. + // + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + options.set_buffer_hint(); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used for sending + /// trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of \a status, + /// it may be non-OK + // + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + void Finish(const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&finish_ops_); + + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class ::grpc_impl::Server; + + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + template + void EnsureInitialMetadataSent(T* ops) { + if (!ctx_->sent_initial_metadata_) { + ops->SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops->set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +} // namespace grpc_impl +#endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 5da6a649f14..64ee17dec0d 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -19,299 +19,18 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H #define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -extern CoreCodegenInterface* g_core_codegen_interface; - -/// An interface relevant for async client side unary RPCs (which send -/// one request message to a server and receive one response message). -template -class ClientAsyncResponseReaderInterface { - public: - virtual ~ClientAsyncResponseReaderInterface() {} - - /// Start the call that was set up by the constructor, but only if the - /// constructor was invoked through the "Prepare" API which doesn't actually - /// start the call - virtual void StartCall() = 0; - - /// Request notification of the reading of initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Request to receive the server's response \a msg and final \a status for - /// the call, and to notify \a tag on this call's completion queue when - /// finished. - /// - /// This function will return when either: - /// - when the server's response message and status have been received. - /// - when the server has returned a non-OK status (no message expected in - /// this case). - /// - when the call failed for some reason and the library generated a - /// non-OK status. - /// - /// \param[in] tag Tag identifying this request. - /// \param[out] status To be updated with the operation status. - /// \param[out] msg To be filled in with the server's response message. - virtual void Finish(R* msg, Status* status, void* tag) = 0; -}; - -namespace internal { template -class ClientAsyncResponseReaderFactory { - public: - /// Start a call and write the request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template - static ClientAsyncResponseReader* Create( - ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const W& request, bool start) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncResponseReader))) - ClientAsyncResponseReader(call, context, request, start); - } -}; -} // namespace internal - -/// Async API for client-side unary RPCs, where the message response -/// received from the server is of type \a R. +using ClientAsyncResponseReaderInterface = + grpc_impl::ClientAsyncResponseReaderInterface; template -class ClientAsyncResponseReader final - : public ClientAsyncResponseReaderInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncResponseReader)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall() override { - assert(!started_); - started_ = true; - StartCallInternal(); - } - - /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for - /// semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - single_buf.set_output_tag(tag); - single_buf.RecvInitialMetadata(context_); - call_.PerformOps(&single_buf); - initial_metadata_read_ = true; - } - - /// See \a ClientAysncResponseReaderInterface::Finish for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void Finish(R* msg, Status* status, void* tag) override { - assert(started_); - if (initial_metadata_read_) { - finish_buf.set_output_tag(tag); - finish_buf.RecvMessage(msg); - finish_buf.AllowNoMessage(); - finish_buf.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_buf); - } else { - single_buf.set_output_tag(tag); - single_buf.RecvInitialMetadata(context_); - single_buf.RecvMessage(msg); - single_buf.AllowNoMessage(); - single_buf.ClientRecvStatus(context_, status); - call_.PerformOps(&single_buf); - } - } - - private: - friend class internal::ClientAsyncResponseReaderFactory; - ::grpc_impl::ClientContext* const context_; - ::grpc::internal::Call call_; - bool started_; - bool initial_metadata_read_ = false; +using ClientAsyncResponseReader = grpc_impl::ClientAsyncResponseReader; - template - ClientAsyncResponseReader(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, - const W& request, bool start) - : context_(context), call_(call), started_(start) { - // Bind the metadata at time of StartCallInternal but set up the rest here - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok()); - single_buf.ClientSendClose(); - if (start) StartCallInternal(); - } - - void StartCallInternal() { - single_buf.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - - // disable operator new - static void* operator new(std::size_t size); - static void* operator new(std::size_t size, void* p) { return p; } - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose, - ::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - single_buf; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_buf; -}; - -/// Async server-side API for handling unary calls, where the single -/// response message sent to the client is of type \a W. template -class ServerAsyncResponseWriter final - : public internal::ServerAsyncStreamingInterface { - public: - explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Side effect: - /// The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_buf_.set_output_tag(tag); - meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_buf_); - } - - /// Indicate that the stream is to be finished and request notification - /// when the server has sent the appropriate signals to the client to - /// end the call. Should not be used concurrently with other operations. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of the call. - /// \param[in] msg Message to be sent to the client. - /// - /// Side effect: - /// - also sends initial metadata if not already sent (using the - /// \a ServerContext associated with this call). - /// - /// Note: if \a status has a non-OK code, then \a msg will not be sent, - /// and the client will receive only the status with possible trailing - /// metadata. - void Finish(const W& msg, const Status& status, void* tag) { - finish_buf_.set_output_tag(tag); - finish_buf_.set_core_cq_tag(&finish_buf_); - if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_buf_.SendMessage(msg)); - } else { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_buf_); - } - - /// Indicate that the stream is to be finished with a non-OK status, - /// and request notification for when the server has finished sending the - /// appropriate signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of the call. - /// - Note: \a status must have a non-OK code. - /// - /// Side effect: - /// - also sends initial metadata if not already sent (using the - /// \a ServerContext associated with this call). - void FinishWithError(const Status& status, void* tag) { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_buf_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_buf_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_buf_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - finish_buf_; -}; +using ServerAsyncResponseWriter = ::grpc_impl::ServerAsyncResponseWriter; } // namespace grpc -namespace std { -template -class default_delete> { - public: - void operator()(void* p) {} -}; -template -class default_delete> { - public: - void operator()(void* p) {} -}; -} // namespace std - #endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H diff --git a/include/grpcpp/impl/codegen/async_unary_call_impl.h b/include/grpcpp/impl/codegen/async_unary_call_impl.h new file mode 100644 index 00000000000..ff8bf15602b --- /dev/null +++ b/include/grpcpp/impl/codegen/async_unary_call_impl.h @@ -0,0 +1,315 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H +#define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +/// An interface relevant for async client side unary RPCs (which send +/// one request message to a server and receive one response message). +template +class ClientAsyncResponseReaderInterface { + public: + virtual ~ClientAsyncResponseReaderInterface() {} + + /// Start the call that was set up by the constructor, but only if the + /// constructor was invoked through the "Prepare" API which doesn't actually + /// start the call + virtual void StartCall() = 0; + + /// Request notification of the reading of initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// \param[in] tag Tag identifying this request. + virtual void ReadInitialMetadata(void* tag) = 0; + + /// Request to receive the server's response \a msg and final \a status for + /// the call, and to notify \a tag on this call's completion queue when + /// finished. + /// + /// This function will return when either: + /// - when the server's response message and status have been received. + /// - when the server has returned a non-OK status (no message expected in + /// this case). + /// - when the call failed for some reason and the library generated a + /// non-OK status. + /// + /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. + /// \param[out] msg To be filled in with the server's response message. + virtual void Finish(R* msg, ::grpc::Status* status, void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncResponseReaderFactory { + public: + /// Start a call and write the request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template + static ClientAsyncResponseReader* Create( + ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request, bool start) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncResponseReader))) + ClientAsyncResponseReader(call, context, request, start); + } +}; +} // namespace internal + +/// Async API for client-side unary RPCs, where the message response +/// received from the server is of type \a R. +template +class ClientAsyncResponseReader final + : public ClientAsyncResponseReaderInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncResponseReader)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + assert(!started_); + started_ = true; + StartCallInternal(); + } + + /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for + /// semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + single_buf.set_output_tag(tag); + single_buf.RecvInitialMetadata(context_); + call_.PerformOps(&single_buf); + initial_metadata_read_ = true; + } + + /// See \a ClientAysncResponseReaderInterface::Finish for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void Finish(R* msg, ::grpc::Status* status, void* tag) override { + assert(started_); + if (initial_metadata_read_) { + finish_buf.set_output_tag(tag); + finish_buf.RecvMessage(msg); + finish_buf.AllowNoMessage(); + finish_buf.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_buf); + } else { + single_buf.set_output_tag(tag); + single_buf.RecvInitialMetadata(context_); + single_buf.RecvMessage(msg); + single_buf.AllowNoMessage(); + single_buf.ClientRecvStatus(context_, status); + call_.PerformOps(&single_buf); + } + } + + private: + friend class internal::ClientAsyncResponseReaderFactory; + ::grpc_impl::ClientContext* const context_; + ::grpc::internal::Call call_; + bool started_; + bool initial_metadata_read_ = false; + + template + ClientAsyncResponseReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + const W& request, bool start) + : context_(context), call_(call), started_(start) { + // Bind the metadata at time of StartCallInternal but set up the rest here + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok()); + single_buf.ClientSendClose(); + if (start) StartCallInternal(); + } + + void StartCallInternal() { + single_buf.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + + // disable operator new + static void* operator new(std::size_t size); + static void* operator new(std::size_t size, void* p) { return p; } + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose, + ::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + single_buf; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_buf; +}; + +/// Async server-side API for handling unary calls, where the single +/// response message sent to the client is of type \a W. +template +class ServerAsyncResponseWriter final + : public ::grpc::internal::ServerAsyncStreamingInterface { + public: + explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Side effect: + /// The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_buf_.set_output_tag(tag); + meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_buf_); + } + + /// Indicate that the stream is to be finished and request notification + /// when the server has sent the appropriate signals to the client to + /// end the call. Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// \param[in] msg Message to be sent to the client. + /// + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). + /// + /// Note: if \a status has a non-OK code, then \a msg will not be sent, + /// and the client will receive only the status with possible trailing + /// metadata. + void Finish(const W& msg, const ::grpc::Status& status, void* tag) { + finish_buf_.set_output_tag(tag); + finish_buf_.set_core_cq_tag(&finish_buf_); + if (!ctx_->sent_initial_metadata_) { + finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (status.ok()) { + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_buf_.SendMessage(msg)); + } else { + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); + } + call_.PerformOps(&finish_buf_); + } + + /// Indicate that the stream is to be finished with a non-OK status, + /// and request notification for when the server has finished sending the + /// appropriate signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// - Note: \a status must have a non-OK code. + /// + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). + void FinishWithError(const ::grpc::Status& status, void* tag) { + GPR_CODEGEN_ASSERT(!status.ok()); + finish_buf_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_buf_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_buf_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + finish_buf_; +}; + +} // namespace grpc_impl + +namespace std { +template +class default_delete<::grpc_impl::ClientAsyncResponseReader> { + public: + void operator()(void* p) {} +}; +template +class default_delete<::grpc_impl::ClientAsyncResponseReaderInterface> { + public: + void operator()(void* p) {} +}; +} // namespace std + +#endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index e2ba9344bcb..0b7be6fc753 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -29,6 +29,17 @@ #include +namespace grpc_impl { +namespace internal { + +template +class CallbackUnaryHandler; +template +class CallbackServerStreamingHandler; + +} // namespace internal +} // namespace grpc_impl + namespace grpc { class ServerInterface; @@ -45,10 +56,6 @@ template class RpcMethodHandler; template class ServerStreamingHandler; -template -class CallbackUnaryHandler; -template -class CallbackServerStreamingHandler; template class ErrorMethodHandler; class ExternalConnectionAcceptorImpl; @@ -176,9 +183,9 @@ class ByteBuffer final { template friend class internal::ServerStreamingHandler; template - friend class internal::CallbackUnaryHandler; + friend class ::grpc_impl::internal::CallbackUnaryHandler; template - friend class ::grpc::internal::CallbackServerStreamingHandler; + friend class ::grpc_impl::internal::CallbackServerStreamingHandler; template friend class internal::ErrorMethodHandler; template diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index d0958bbb251..84d1407cbe2 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 836c287e509..dd2fe8d687a 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -27,24 +27,13 @@ namespace grpc_impl { class ClientContext; class CompletionQueue; -} // namespace grpc_impl - -namespace grpc { -class ChannelInterface; - template class ClientReader; template class ClientWriter; template class ClientReaderWriter; - namespace internal { -class Call; -class CallOpSetInterface; -class RpcMethod; -template -class BlockingUnaryCallImpl; template class CallbackUnaryCallImpl; template @@ -62,7 +51,19 @@ class ClientCallbackReaderFactory; template class ClientCallbackWriterFactory; class ClientCallbackUnaryFactory; +} // namespace internal +} // namespace grpc_impl + +namespace grpc { +class ChannelInterface; + +namespace internal { +class Call; +class CallOpSetInterface; +class RpcMethod; class InterceptedChannel; +template +class BlockingUnaryCallImpl; } // namespace internal /// Codegen interface for \a grpc::Channel. @@ -102,30 +103,30 @@ class ChannelInterface { private: template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::internal::ClientAsyncReaderFactory; + friend class ::grpc_impl::internal::ClientAsyncReaderFactory; template - friend class ::grpc::internal::ClientAsyncWriterFactory; + friend class ::grpc_impl::internal::ClientAsyncWriterFactory; template - friend class ::grpc::internal::ClientAsyncReaderWriterFactory; + friend class ::grpc_impl::internal::ClientAsyncReaderWriterFactory; template - friend class ::grpc::internal::ClientAsyncResponseReaderFactory; + friend class ::grpc_impl::internal::ClientAsyncResponseReaderFactory; template - friend class ::grpc::internal::ClientCallbackReaderWriterFactory; + friend class ::grpc_impl::internal::ClientCallbackReaderWriterFactory; template - friend class ::grpc::internal::ClientCallbackReaderFactory; + friend class ::grpc_impl::internal::ClientCallbackReaderFactory; template - friend class ::grpc::internal::ClientCallbackWriterFactory; - friend class ::grpc::internal::ClientCallbackUnaryFactory; + friend class ::grpc_impl::internal::ClientCallbackWriterFactory; + friend class ::grpc_impl::internal::ClientCallbackUnaryFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template - friend class ::grpc::internal::CallbackUnaryCallImpl; + friend class ::grpc_impl::internal::CallbackUnaryCallImpl; friend class ::grpc::internal::RpcMethod; friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 9441a48b051..4f60741624a 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -19,1012 +19,25 @@ #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace grpc_impl { -class Channel; -class ClientContext; -} // namespace grpc_impl +#include namespace grpc { - -namespace internal { -class RpcMethod; - -/// Perform a callback-based unary call -/// TODO(vjpai): Combine as much as possible with the blocking unary call code -template -void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ::grpc_impl::ClientContext* context, - const InputMessage* request, OutputMessage* result, - std::function on_completion) { - CallbackUnaryCallImpl x( - channel, method, context, request, result, on_completion); -} - -template -class CallbackUnaryCallImpl { - public: - CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ::grpc_impl::ClientContext* context, - const InputMessage* request, OutputMessage* result, - std::function on_completion) { - CompletionQueue* cq = channel->CallbackCQ(); - GPR_CODEGEN_ASSERT(cq != nullptr); - Call call(channel->CreateCall(method, context, cq)); - - using FullCallOpSet = - CallOpSet, - CallOpClientSendClose, CallOpClientRecvStatus>; - - auto* ops = new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(FullCallOpSet))) FullCallOpSet; - - auto* tag = new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(CallbackWithStatusTag))) - CallbackWithStatusTag(call.call(), on_completion, ops); - - // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessagePtr(request); - if (!s.ok()) { - tag->force_run(s); - return; - } - ops->SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - ops->RecvInitialMetadata(context); - ops->RecvMessage(result); - ops->AllowNoMessage(); - ops->ClientSendClose(); - ops->ClientRecvStatus(context, tag->status_ptr()); - ops->set_core_cq_tag(tag); - call.PerformOps(ops); - } -}; -} // namespace internal - namespace experimental { -// Forward declarations -template -class ClientBidiReactor; template -class ClientReadReactor; -template -class ClientWriteReactor; -class ClientUnaryReactor; - -// NOTE: The streaming objects are not actually implemented in the public API. -// These interfaces are provided for mocking only. Typical applications -// will interact exclusively with the reactors that they define. -template -class ClientCallbackReaderWriter { - public: - virtual ~ClientCallbackReaderWriter() {} - virtual void StartCall() = 0; - virtual void Write(const Request* req, WriteOptions options) = 0; - virtual void WritesDone() = 0; - virtual void Read(Response* resp) = 0; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientBidiReactor* reactor) { - reactor->BindStream(this); - } -}; - -template -class ClientCallbackReader { - public: - virtual ~ClientCallbackReader() {} - virtual void StartCall() = 0; - virtual void Read(Response* resp) = 0; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientReadReactor* reactor) { - reactor->BindReader(this); - } -}; +using ClientReadReactor = + ::grpc_impl::experimental::ClientReadReactor; template -class ClientCallbackWriter { - public: - virtual ~ClientCallbackWriter() {} - virtual void StartCall() = 0; - void Write(const Request* req) { Write(req, WriteOptions()); } - virtual void Write(const Request* req, WriteOptions options) = 0; - void WriteLast(const Request* req, WriteOptions options) { - Write(req, options.set_last_message()); - } - virtual void WritesDone() = 0; +using ClientWriteReactor = + ::grpc_impl::experimental::ClientWriteReactor; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientWriteReactor* reactor) { - reactor->BindWriter(this); - } -}; - -class ClientCallbackUnary { - public: - virtual ~ClientCallbackUnary() {} - virtual void StartCall() = 0; - - protected: - void BindReactor(ClientUnaryReactor* reactor); -}; - -// The following classes are the reactor interfaces that are to be implemented -// by the user. They are passed in to the library as an argument to a call on a -// stub (either a codegen-ed call or a generic call). The streaming RPC is -// activated by calling StartCall, possibly after initiating StartRead, -// StartWrite, or AddHold operations on the streaming object. Note that none of -// the classes are pure; all reactions have a default empty reaction so that the -// user class only needs to override those classes that it cares about. -// The reactor must be passed to the stub invocation before any of the below -// operations can be called. - -/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. template -class ClientBidiReactor { - public: - virtual ~ClientBidiReactor() {} - - /// Activate the RPC and initiate any reads or writes that have been Start'ed - /// before this call. All streaming RPCs issued by the client MUST have - /// StartCall invoked on them (even if they are canceled) as this call is the - /// activation of their lifecycle. - void StartCall() { stream_->StartCall(); } - - /// Initiate a read operation (or post it for later initiation if StartCall - /// has not yet been invoked). - /// - /// \param[out] resp Where to eventually store the read message. Valid when - /// the library calls OnReadDone - void StartRead(Response* resp) { stream_->Read(resp); } - - /// Initiate a write operation (or post it for later initiation if StartCall - /// has not yet been invoked). - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } - - /// Initiate/post a write operation with specified options. - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - /// \param[in] options The WriteOptions to use for writing this message - void StartWrite(const Request* req, WriteOptions options) { - stream_->Write(req, std::move(options)); - } - - /// Initiate/post a write operation with specified options and an indication - /// that this is the last write (like StartWrite and StartWritesDone, merged). - /// Note that calling this means that no more calls to StartWrite, - /// StartWriteLast, or StartWritesDone are allowed. - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - /// \param[in] options The WriteOptions to use for writing this message - void StartWriteLast(const Request* req, WriteOptions options) { - StartWrite(req, std::move(options.set_last_message())); - } - - /// Indicate that the RPC will have no more write operations. This can only be - /// issued once for a given RPC. This is not required or allowed if - /// StartWriteLast is used since that already has the same implication. - /// Note that calling this means that no more calls to StartWrite, - /// StartWriteLast, or StartWritesDone are allowed. - void StartWritesDone() { stream_->WritesDone(); } - - /// Holds are needed if (and only if) this stream has operations that take - /// place on it after StartCall but from outside one of the reactions - /// (OnReadDone, etc). This is _not_ a common use of the streaming API. - /// - /// Holds must be added before calling StartCall. If a stream still has a hold - /// in place, its resources will not be destroyed even if the status has - /// already come in from the wire and there are currently no active callbacks - /// outstanding. Similarly, the stream will not call OnDone if there are still - /// holds on it. - /// - /// For example, if a StartRead or StartWrite operation is going to be - /// initiated from elsewhere in the application, the application should call - /// AddHold or AddMultipleHolds before StartCall. If there is going to be, - /// for example, a read-flow and a write-flow taking place outside the - /// reactions, then call AddMultipleHolds(2) before StartCall. When the - /// application knows that it won't issue any more read operations (such as - /// when a read comes back as not ok), it should issue a RemoveHold(). It - /// should also call RemoveHold() again after it does StartWriteLast or - /// StartWritesDone that indicates that there will be no more write ops. - /// The number of RemoveHold calls must match the total number of AddHold - /// calls plus the number of holds added by AddMultipleHolds. - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { stream_->AddHold(holds); } - void RemoveHold() { stream_->RemoveHold(); } - - /// Notifies the application that all operations associated with this RPC - /// have completed and provides the RPC status outcome. - /// - /// \param[in] s The status outcome of this RPC - virtual void OnDone(const Status& s) {} - - /// Notifies the application that a read of initial metadata from the - /// server is done. If the application chooses not to implement this method, - /// it can assume that the initial metadata has been read before the first - /// call of OnReadDone or OnDone. - /// - /// \param[in] ok Was the initial metadata read successfully? If false, no - /// further read-side operation will succeed. - virtual void OnReadInitialMetadataDone(bool ok) {} - - /// Notifies the application that a StartRead operation completed. - /// - /// \param[in] ok Was it successful? If false, no further read-side operation - /// will succeed. - virtual void OnReadDone(bool ok) {} - - /// Notifies the application that a StartWrite operation completed. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnWriteDone(bool ok) {} - - /// Notifies the application that a StartWritesDone operation completed. Note - /// that this is only used on explicit StartWritesDone operations and not for - /// those that are implicitly invoked as part of a StartWriteLast. - /// - /// \param[in] ok Was it successful? If false, the application will later see - /// the failure reflected as a bad status in OnDone. - virtual void OnWritesDoneDone(bool ok) {} - - private: - friend class ClientCallbackReaderWriter; - void BindStream(ClientCallbackReaderWriter* stream) { - stream_ = stream; - } - ClientCallbackReaderWriter* stream_; -}; - -/// \a ClientReadReactor is the interface for a server-streaming RPC. -/// All public methods behave as in ClientBidiReactor. -template -class ClientReadReactor { - public: - virtual ~ClientReadReactor() {} - - void StartCall() { reader_->StartCall(); } - void StartRead(Response* resp) { reader_->Read(resp); } - - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { reader_->AddHold(holds); } - void RemoveHold() { reader_->RemoveHold(); } - - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - - private: - friend class ClientCallbackReader; - void BindReader(ClientCallbackReader* reader) { reader_ = reader; } - ClientCallbackReader* reader_; -}; - -/// \a ClientWriteReactor is the interface for a client-streaming RPC. -/// All public methods behave as in ClientBidiReactor. -template -class ClientWriteReactor { - public: - virtual ~ClientWriteReactor() {} - - void StartCall() { writer_->StartCall(); } - void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } - void StartWrite(const Request* req, WriteOptions options) { - writer_->Write(req, std::move(options)); - } - void StartWriteLast(const Request* req, WriteOptions options) { - StartWrite(req, std::move(options.set_last_message())); - } - void StartWritesDone() { writer_->WritesDone(); } - - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { writer_->AddHold(holds); } - void RemoveHold() { writer_->RemoveHold(); } - - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} - - private: - friend class ClientCallbackWriter; - void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } - ClientCallbackWriter* writer_; -}; - -/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. -/// This is _not_ a common way of invoking a unary RPC. In practice, this -/// option should be used only if the unary RPC wants to receive initial -/// metadata without waiting for the response to complete. Most deployments of -/// RPC systems do not use this option, but it is needed for generality. -/// All public methods behave as in ClientBidiReactor. -/// StartCall is included for consistency with the other reactor flavors: even -/// though there are no StartRead or StartWrite operations to queue before the -/// call (that is part of the unary call itself) and there is no reactor object -/// being created as a result of this call, we keep a consistent 2-phase -/// initiation API among all the reactor flavors. -class ClientUnaryReactor { - public: - virtual ~ClientUnaryReactor() {} - - void StartCall() { call_->StartCall(); } - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - - private: - friend class ClientCallbackUnary; - void BindCall(ClientCallbackUnary* call) { call_ = call; } - ClientCallbackUnary* call_; -}; - -// Define function out-of-line from class to avoid forward declaration issue -inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { - reactor->BindCall(this); -} +using ClientBidiReactor = + ::grpc_impl::experimental::ClientBidiReactor; +typedef ::grpc_impl::experimental::ClientUnaryReactor ClientUnaryReactor; } // namespace experimental - -namespace internal { - -// Forward declare factory classes for friendship -template -class ClientCallbackReaderWriterFactory; -template -class ClientCallbackReaderFactory; -template -class ClientCallbackWriterFactory; - -template -class ClientCallbackReaderWriterImpl - : public ::grpc::experimental::ClientCallbackReaderWriter { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackReaderWriterImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackReaderWriterImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any read backlog - // 3. Any write backlog - // 4. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - if (!start_corked_) { - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read and write tags so that they don't have to be set up - // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - if (read_ops_at_start_) { - call_.PerformOps(&read_ops_); - } - - if (write_ops_at_start_) { - call_.PerformOps(&write_ops_); - } - - if (writes_done_ops_at_start_) { - call_.PerformOps(&writes_done_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Read(Response* msg) override { - read_ops_.RecvMessage(msg); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&read_ops_); - } else { - read_ops_at_start_ = true; - } - } - - void Write(const Request* msg, WriteOptions options) override { - if (start_corked_) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&write_ops_); - } else { - write_ops_at_start_ = true; - } - } - void WritesDone() override { - if (start_corked_) { - writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); - writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&writes_done_ops_); - } else { - writes_done_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackReaderWriterFactory; - - ClientCallbackReaderWriterImpl( - Call call, ::grpc_impl::ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) - : context_(context), - call_(call), - reactor_(reactor), - start_corked_(context_->initial_metadata_corked_) { - this->BindReactor(reactor); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientBidiReactor* const reactor_; - - CallOpSet start_ops_; - CallbackWithSuccessTag start_tag_; - bool start_corked_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet - write_ops_; - CallbackWithSuccessTag write_tag_; - bool write_ops_at_start_{false}; - - CallOpSet writes_done_ops_; - CallbackWithSuccessTag writes_done_tag_; - bool writes_done_ops_at_start_{false}; - - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - bool read_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackReaderWriterFactory { - public: - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackReaderWriterImpl))) - ClientCallbackReaderWriterImpl(call, context, - reactor); - } -}; - -template -class ClientCallbackReaderImpl - : public ::grpc::experimental::ClientCallbackReader { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackReaderImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackReaderImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any backlog - // 3. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read tag so it doesn't have to be set up each time - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - if (read_ops_at_start_) { - call_.PerformOps(&read_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Read(Response* msg) override { - read_ops_.RecvMessage(msg); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&read_ops_); - } else { - read_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackReaderFactory; - - template - ClientCallbackReaderImpl( - Call call, ::grpc_impl::ClientContext* context, Request* request, - ::grpc::experimental::ClientReadReactor* reactor) - : context_(context), call_(call), reactor_(reactor) { - this->BindReactor(reactor); - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); - start_ops_.ClientSendClose(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientReadReactor* const reactor_; - - CallOpSet - start_ops_; - CallbackWithSuccessTag start_tag_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - bool read_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackReaderFactory { - public: - template - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const Request* request, - ::grpc::experimental::ClientReadReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackReaderImpl))) - ClientCallbackReaderImpl(call, context, request, reactor); - } -}; - -template -class ClientCallbackWriterImpl - : public ::grpc::experimental::ClientCallbackWriter { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackWriterImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackWriterImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any backlog - // 3. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - if (!start_corked_) { - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read and write tags so that they don't have to be set up - // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - - if (write_ops_at_start_) { - call_.PerformOps(&write_ops_); - } - - if (writes_done_ops_at_start_) { - call_.PerformOps(&writes_done_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Write(const Request* msg, WriteOptions options) override { - if (start_corked_) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&write_ops_); - } else { - write_ops_at_start_ = true; - } - } - void WritesDone() override { - if (start_corked_) { - writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); - writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&writes_done_ops_); - } else { - writes_done_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackWriterFactory; - - template - ClientCallbackWriterImpl( - Call call, ::grpc_impl::ClientContext* context, Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) - : context_(context), - call_(call), - reactor_(reactor), - start_corked_(context_->initial_metadata_corked_) { - this->BindReactor(reactor); - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientWriteReactor* const reactor_; - - CallOpSet start_ops_; - CallbackWithSuccessTag start_tag_; - bool start_corked_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet - write_ops_; - CallbackWithSuccessTag write_tag_; - bool write_ops_at_start_{false}; - - CallOpSet writes_done_ops_; - CallbackWithSuccessTag writes_done_tag_; - bool writes_done_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackWriterFactory { - public: - template - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackWriterImpl))) - ClientCallbackWriterImpl(call, context, response, reactor); - } -}; - -class ClientCallbackUnaryImpl final - : public ::grpc::experimental::ClientCallbackUnary { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackUnaryImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall() override { - // This call initiates two batches, each with a callback - // 1. Send initial metadata + write + writes done + recv initial metadata - // 2. Read message, recv trailing metadata - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackUnaryImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - private: - friend class ClientCallbackUnaryFactory; - - template - ClientCallbackUnaryImpl(Call call, ::grpc_impl::ClientContext* context, - Request* request, Response* response, - ::grpc::experimental::ClientUnaryReactor* reactor) - : context_(context), call_(call), reactor_(reactor) { - this->BindReactor(reactor); - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); - start_ops_.ClientSendClose(); - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientUnaryReactor* const reactor_; - - CallOpSet - start_ops_; - CallbackWithSuccessTag start_tag_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - // This call will have 2 callbacks: start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -class ClientCallbackUnaryFactory { - public: - template - static void Create(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const Request* request, Response* response, - ::grpc::experimental::ClientUnaryReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackUnaryImpl))) - ClientCallbackUnaryImpl(call, context, request, response, reactor); - } -}; - -} // namespace internal } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/client_callback_impl.h b/include/grpcpp/impl/codegen/client_callback_impl.h new file mode 100644 index 00000000000..81847bc9e04 --- /dev/null +++ b/include/grpcpp/impl/codegen/client_callback_impl.h @@ -0,0 +1,1067 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +namespace internal { +class RpcMethod; +} // namespace internal +} // namespace grpc + +namespace grpc_impl { +class Channel; +class ClientContext; + +namespace internal { + +/// Perform a callback-based unary call +/// TODO(vjpai): Combine as much as possible with the blocking unary call code +template +void CallbackUnaryCall(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, + std::function on_completion) { + CallbackUnaryCallImpl x( + channel, method, context, request, result, on_completion); +} + +template +class CallbackUnaryCallImpl { + public: + CallbackUnaryCallImpl(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, + std::function on_completion) { + ::grpc_impl::CompletionQueue* cq = channel->CallbackCQ(); + GPR_CODEGEN_ASSERT(cq != nullptr); + grpc::internal::Call call(channel->CreateCall(method, context, cq)); + + using FullCallOpSet = grpc::internal::CallOpSet< + ::grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpSendMessage, + grpc::internal::CallOpRecvInitialMetadata, + grpc::internal::CallOpRecvMessage, + grpc::internal::CallOpClientSendClose, + grpc::internal::CallOpClientRecvStatus>; + + auto* ops = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(FullCallOpSet))) FullCallOpSet; + + auto* tag = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(grpc::internal::CallbackWithStatusTag))) + grpc::internal::CallbackWithStatusTag(call.call(), on_completion, ops); + + // TODO(vjpai): Unify code with sync API as much as possible + ::grpc::Status s = ops->SendMessagePtr(request); + if (!s.ok()) { + tag->force_run(s); + return; + } + ops->SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + ops->RecvInitialMetadata(context); + ops->RecvMessage(result); + ops->AllowNoMessage(); + ops->ClientSendClose(); + ops->ClientRecvStatus(context, tag->status_ptr()); + ops->set_core_cq_tag(tag); + call.PerformOps(ops); + } +}; +} // namespace internal + +namespace experimental { + +// Forward declarations +template +class ClientBidiReactor; +template +class ClientReadReactor; +template +class ClientWriteReactor; +class ClientUnaryReactor; + +// NOTE: The streaming objects are not actually implemented in the public API. +// These interfaces are provided for mocking only. Typical applications +// will interact exclusively with the reactors that they define. +template +class ClientCallbackReaderWriter { + public: + virtual ~ClientCallbackReaderWriter() {} + virtual void StartCall() = 0; + virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0; + virtual void WritesDone() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientBidiReactor* reactor) { + reactor->BindStream(this); + } +}; + +template +class ClientCallbackReader { + public: + virtual ~ClientCallbackReader() {} + virtual void StartCall() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientReadReactor* reactor) { + reactor->BindReader(this); + } +}; + +template +class ClientCallbackWriter { + public: + virtual ~ClientCallbackWriter() {} + virtual void StartCall() = 0; + void Write(const Request* req) { Write(req, ::grpc::WriteOptions()); } + virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0; + void WriteLast(const Request* req, ::grpc::WriteOptions options) { + Write(req, options.set_last_message()); + } + virtual void WritesDone() = 0; + + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +class ClientCallbackUnary { + public: + virtual ~ClientCallbackUnary() {} + virtual void StartCall() = 0; + + protected: + void BindReactor(ClientUnaryReactor* reactor); +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user. They are passed in to the library as an argument to a call on a +// stub (either a codegen-ed call or a generic call). The streaming RPC is +// activated by calling StartCall, possibly after initiating StartRead, +// StartWrite, or AddHold operations on the streaming object. Note that none of +// the classes are pure; all reactions have a default empty reaction so that the +// user class only needs to override those classes that it cares about. +// The reactor must be passed to the stub invocation before any of the below +// operations can be called. + +/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. +template +class ClientBidiReactor { + public: + virtual ~ClientBidiReactor() {} + + /// Activate the RPC and initiate any reads or writes that have been Start'ed + /// before this call. All streaming RPCs issued by the client MUST have + /// StartCall invoked on them (even if they are canceled) as this call is the + /// activation of their lifecycle. + void StartCall() { stream_->StartCall(); } + + /// Initiate a read operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[out] resp Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Response* resp) { stream_->Read(resp); } + + /// Initiate a write operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + void StartWrite(const Request* req) { + StartWrite(req, ::grpc::WriteOptions()); + } + + /// Initiate/post a write operation with specified options. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Request* req, ::grpc::WriteOptions options) { + stream_->Write(req, std::move(options)); + } + + /// Initiate/post a write operation with specified options and an indication + /// that this is the last write (like StartWrite and StartWritesDone, merged). + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Request* req, ::grpc::WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + + /// Indicate that the RPC will have no more write operations. This can only be + /// issued once for a given RPC. This is not required or allowed if + /// StartWriteLast is used since that already has the same implication. + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + void StartWritesDone() { stream_->WritesDone(); } + + /// Holds are needed if (and only if) this stream has operations that take + /// place on it after StartCall but from outside one of the reactions + /// (OnReadDone, etc). This is _not_ a common use of the streaming API. + /// + /// Holds must be added before calling StartCall. If a stream still has a hold + /// in place, its resources will not be destroyed even if the status has + /// already come in from the wire and there are currently no active callbacks + /// outstanding. Similarly, the stream will not call OnDone if there are still + /// holds on it. + /// + /// For example, if a StartRead or StartWrite operation is going to be + /// initiated from elsewhere in the application, the application should call + /// AddHold or AddMultipleHolds before StartCall. If there is going to be, + /// for example, a read-flow and a write-flow taking place outside the + /// reactions, then call AddMultipleHolds(2) before StartCall. When the + /// application knows that it won't issue any more read operations (such as + /// when a read comes back as not ok), it should issue a RemoveHold(). It + /// should also call RemoveHold() again after it does StartWriteLast or + /// StartWritesDone that indicates that there will be no more write ops. + /// The number of RemoveHold calls must match the total number of AddHold + /// calls plus the number of holds added by AddMultipleHolds. + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { stream_->AddHold(holds); } + void RemoveHold() { stream_->RemoveHold(); } + + /// Notifies the application that all operations associated with this RPC + /// have completed and provides the RPC status outcome. + /// + /// \param[in] s The status outcome of this RPC + virtual void OnDone(const ::grpc::Status& s) {} + + /// Notifies the application that a read of initial metadata from the + /// server is done. If the application chooses not to implement this method, + /// it can assume that the initial metadata has been read before the first + /// call of OnReadDone or OnDone. + /// + /// \param[in] ok Was the initial metadata read successfully? If false, no + /// further read-side operation will succeed. + virtual void OnReadInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite operation completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that a StartWritesDone operation completed. Note + /// that this is only used on explicit StartWritesDone operations and not for + /// those that are implicitly invoked as part of a StartWriteLast. + /// + /// \param[in] ok Was it successful? If false, the application will later see + /// the failure reflected as a bad status in OnDone. + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackReaderWriter; + void BindStream(ClientCallbackReaderWriter* stream) { + stream_ = stream; + } + ClientCallbackReaderWriter* stream_; +}; + +/// \a ClientReadReactor is the interface for a server-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientReadReactor { + public: + virtual ~ClientReadReactor() {} + + void StartCall() { reader_->StartCall(); } + void StartRead(Response* resp) { reader_->Read(resp); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { reader_->AddHold(holds); } + void RemoveHold() { reader_->RemoveHold(); } + + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + + private: + friend class ClientCallbackReader; + void BindReader(ClientCallbackReader* reader) { reader_ = reader; } + ClientCallbackReader* reader_; +}; + +/// \a ClientWriteReactor is the interface for a client-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientWriteReactor { + public: + virtual ~ClientWriteReactor() {} + + void StartCall() { writer_->StartCall(); } + void StartWrite(const Request* req) { + StartWrite(req, ::grpc::WriteOptions()); + } + void StartWrite(const Request* req, ::grpc::WriteOptions options) { + writer_->Write(req, std::move(options)); + } + void StartWriteLast(const Request* req, ::grpc::WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + void StartWritesDone() { writer_->WritesDone(); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { writer_->AddHold(holds); } + void RemoveHold() { writer_->RemoveHold(); } + + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackWriter; + void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } + ClientCallbackWriter* writer_; +}; + +/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. +/// This is _not_ a common way of invoking a unary RPC. In practice, this +/// option should be used only if the unary RPC wants to receive initial +/// metadata without waiting for the response to complete. Most deployments of +/// RPC systems do not use this option, but it is needed for generality. +/// All public methods behave as in ClientBidiReactor. +/// StartCall is included for consistency with the other reactor flavors: even +/// though there are no StartRead or StartWrite operations to queue before the +/// call (that is part of the unary call itself) and there is no reactor object +/// being created as a result of this call, we keep a consistent 2-phase +/// initiation API among all the reactor flavors. +class ClientUnaryReactor { + public: + virtual ~ClientUnaryReactor() {} + + void StartCall() { call_->StartCall(); } + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + + private: + friend class ClientCallbackUnary; + void BindCall(ClientCallbackUnary* call) { call_ = call; } + ClientCallbackUnary* call_; +}; + +// Define function out-of-line from class to avoid forward declaration issue +inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { + reactor->BindCall(this); +} + +} // namespace experimental + +namespace internal { + +// Forward declare factory classes for friendship +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; + +template +class ClientCallbackReaderWriterImpl + : public experimental::ClientCallbackReaderWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderWriterImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any read backlog + // 3. Any write backlog + // 4. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + void Write(const Request* msg, ::grpc::WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderWriterFactory; + + ClientCallbackReaderWriterImpl( + grpc::internal::Call call, ::grpc_impl::ClientContext* context, + experimental::ClientBidiReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientBidiReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + bool start_corked_; + + grpc::internal::CallOpSet finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + grpc::internal::CallOpSet + writes_done_ops_; + grpc::internal::CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderWriterFactory { + public: + static void Create( + ::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + experimental::ClientBidiReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderWriterImpl))) + ClientCallbackReaderWriterImpl(call, context, + reactor); + } +}; + +template +class ClientCallbackReaderImpl + : public experimental::ClientCallbackReader { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read tag so it doesn't have to be set up each time + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderFactory; + + template + ClientCallbackReaderImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + Request* request, + experimental::ClientReadReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientReadReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + + grpc::internal::CallOpSet finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const Request* request, + experimental::ClientReadReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderImpl))) + ClientCallbackReaderImpl(call, context, request, reactor); + } +}; + +template +class ClientCallbackWriterImpl + : public experimental::ClientCallbackWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackWriterImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Write(const Request* msg, ::grpc::WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackWriterFactory; + + template + ClientCallbackWriterImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + Response* response, + experimental::ClientWriteReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientWriteReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + bool start_corked_; + + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + grpc::internal::CallOpSet + writes_done_ops_; + grpc::internal::CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackWriterFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, Response* response, + experimental::ClientWriteReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackWriterImpl))) + ClientCallbackWriterImpl(call, context, response, reactor); + } +}; + +class ClientCallbackUnaryImpl final : public experimental::ClientCallbackUnary { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackUnaryImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + // This call initiates two batches, each with a callback + // 1. Send initial metadata + write + writes done + recv initial metadata + // 2. Read message, recv trailing metadata + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackUnaryImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + private: + friend class ClientCallbackUnaryFactory; + + template + ClientCallbackUnaryImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, Request* request, + Response* response, + experimental::ClientUnaryReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientUnaryReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + // This call will have 2 callbacks: start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +class ClientCallbackUnaryFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const Request* request, Response* response, + experimental::ClientUnaryReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackUnaryImpl))) + ClientCallbackUnaryImpl(call, context, request, response, reactor); + } +}; + +} // namespace internal +} // namespace grpc_impl +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_context_impl.h b/include/grpcpp/impl/codegen/client_context_impl.h index 8491215cf0e..638ea641bed 100644 --- a/include/grpcpp/impl/codegen/client_context_impl.h +++ b/include/grpcpp/impl/codegen/client_context_impl.h @@ -63,10 +63,19 @@ class ChannelInterface; namespace internal { class RpcMethod; -class CallOpClientRecvStatus; -class CallOpRecvInitialMetadata; template class BlockingUnaryCallImpl; +class CallOpClientRecvStatus; +class CallOpRecvInitialMetadata; +} // namespace internal + +namespace testing { +class InteropClientContextInspector; +} // namespace testing +} // namespace grpc +namespace grpc_impl { + +namespace internal { template class CallbackUnaryCallImpl; template @@ -78,6 +87,10 @@ class ClientCallbackWriterImpl; class ClientCallbackUnaryImpl; } // namespace internal +class CallCredentials; +class Channel; +class CompletionQueue; +class ServerContext; template class ClientReader; template @@ -93,17 +106,6 @@ class ClientAsyncReaderWriter; template class ClientAsyncResponseReader; -namespace testing { -class InteropClientContextInspector; -} // namespace testing -} // namespace grpc -namespace grpc_impl { - -class CallCredentials; -class Channel; -class CompletionQueue; -class ServerContext; - /// Options for \a ClientContext::FromServerContext specifying which traits from /// the \a ServerContext to propagate (copy) from it into a new \a /// ClientContext. @@ -398,30 +400,30 @@ class ClientContext { friend class ::grpc::internal::CallOpRecvInitialMetadata; friend class ::grpc_impl::Channel; template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::ClientAsyncReader; + friend class ::grpc_impl::ClientAsyncReader; template - friend class ::grpc::ClientAsyncWriter; + friend class ::grpc_impl::ClientAsyncWriter; template - friend class ::grpc::ClientAsyncReaderWriter; + friend class ::grpc_impl::ClientAsyncReaderWriter; template - friend class ::grpc::ClientAsyncResponseReader; + friend class ::grpc_impl::ClientAsyncResponseReader; template friend class ::grpc::internal::BlockingUnaryCallImpl; template - friend class ::grpc::internal::CallbackUnaryCallImpl; + friend class ::grpc_impl::internal::CallbackUnaryCallImpl; template - friend class ::grpc::internal::ClientCallbackReaderWriterImpl; + friend class ::grpc_impl::internal::ClientCallbackReaderWriterImpl; template - friend class ::grpc::internal::ClientCallbackReaderImpl; + friend class ::grpc_impl::internal::ClientCallbackReaderImpl; template - friend class ::grpc::internal::ClientCallbackWriterImpl; - friend class ::grpc::internal::ClientCallbackUnaryImpl; + friend class ::grpc_impl::internal::ClientCallbackWriterImpl; + friend class ::grpc_impl::internal::ClientCallbackUnaryImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index 599dd1ecac9..7f80e571c07 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -49,10 +49,10 @@ class BlockingUnaryCallImpl { BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, grpc_impl::ClientContext* context, const InputMessage& request, OutputMessage* result) { - CompletionQueue cq(grpc_completion_queue_attributes{ + ::grpc_impl::CompletionQueue cq(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, nullptr}); // Pluckable completion queue - Call call(channel->CreateCall(method, context, &cq)); + ::grpc::internal::Call call(channel->CreateCall(method, context, &cq)); CallOpSet, CallOpClientSendClose, CallOpClientRecvStatus> diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index 0a6b0b0977b..7716a57e84a 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -47,9 +47,6 @@ class Channel; class Server; class ServerBuilder; class ServerContext; -} // namespace grpc_impl -namespace grpc { - template class ClientReader; template @@ -64,6 +61,8 @@ namespace internal { template class ServerReaderWriterBody; } // namespace internal +} // namespace grpc_impl +namespace grpc { class ChannelInterface; class ServerInterface; @@ -255,17 +254,17 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { // Friend synchronous wrappers so that they can access Pluck(), which is // a semi-private API geared towards the synchronous implementation. template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::ServerReader; + friend class ::grpc_impl::ServerReader; template - friend class ::grpc::ServerWriter; + friend class ::grpc_impl::ServerWriter; template - friend class ::grpc::internal::ServerReaderWriterBody; + friend class ::grpc_impl::internal::ServerReaderWriterBody; template friend class ::grpc::internal::RpcMethodHandler; template diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 36ae19c5bec..cb771a662b9 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -19,1141 +19,26 @@ #ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -// Declare base class of all reactors as internal -namespace internal { - -// Forward declarations -template -class CallbackClientStreamingHandler; -template -class CallbackServerStreamingHandler; -template -class CallbackBidiHandler; - -class ServerReactor { - public: - virtual ~ServerReactor() = default; - virtual void OnDone() = 0; - virtual void OnCancel() = 0; - - private: - friend class ::grpc_impl::ServerContext; - template - friend class CallbackClientStreamingHandler; - template - friend class CallbackServerStreamingHandler; - template - friend class CallbackBidiHandler; - - // The ServerReactor is responsible for tracking when it is safe to call - // OnCancel. This function should not be called until after OnStarted is done - // and the RPC has completed with a cancellation. This is tracked by counting - // how many of these conditions have been met and calling OnCancel when none - // remain unmet. - - void MaybeCallOnCancel() { - if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - OnCancel(); - } - } - - std::atomic on_cancel_conditions_remaining_{2}; -}; - -template -class DefaultMessageHolder - : public experimental::MessageHolder { - public: - DefaultMessageHolder() { - this->set_request(&request_obj_); - this->set_response(&response_obj_); - } - void Release() override { - // the object is allocated in the call arena. - this->~DefaultMessageHolder(); - } - - private: - Request request_obj_; - Response response_obj_; -}; - -} // namespace internal - namespace experimental { - -// Forward declarations -template -class ServerReadReactor; -template -class ServerWriteReactor; -template -class ServerBidiReactor; - -// For unary RPCs, the exposed controller class is only an interface -// and the actual implementation is an internal class. -class ServerCallbackRpcController { - public: - virtual ~ServerCallbackRpcController() = default; - - // The method handler must call this function when it is done so that - // the library knows to free its resources - virtual void Finish(Status s) = 0; - - // Allow the method handler to push out the initial metadata before - // the response and status are ready - virtual void SendInitialMetadata(std::function) = 0; - - /// SetCancelCallback passes in a callback to be called when the RPC is - /// canceled for whatever reason (streaming calls have OnCancel instead). This - /// is an advanced and uncommon use with several important restrictions. This - /// function may not be called more than once on the same RPC. - /// - /// If code calls SetCancelCallback on an RPC, it must also call - /// ClearCancelCallback before calling Finish on the RPC controller. That - /// method makes sure that no cancellation callback is executed for this RPC - /// beyond the point of its return. ClearCancelCallback may be called even if - /// SetCancelCallback was not called for this RPC, and it may be called - /// multiple times. It _must_ be called if SetCancelCallback was called for - /// this RPC. - /// - /// The callback should generally be lightweight and nonblocking and primarily - /// concerned with clearing application state related to the RPC or causing - /// operations (such as cancellations) to happen on dependent RPCs. - /// - /// If the RPC is already canceled at the time that SetCancelCallback is - /// called, the callback is invoked immediately. - /// - /// The cancellation callback may be executed concurrently with the method - /// handler that invokes it but will certainly not issue or execute after the - /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the - /// callback is already executing, the callback will complete its execution - /// before ClearCancelCallback takes effect. - /// - /// To preserve the orderings described above, the callback may be called - /// under a lock that is also used for ClearCancelCallback and - /// ServerContext::IsCancelled, so the callback CANNOT call either of those - /// operations on this RPC or any other function that causes those operations - /// to be called before the callback completes. - virtual void SetCancelCallback(std::function callback) = 0; - virtual void ClearCancelCallback() = 0; - - // NOTE: This is an API for advanced users who need custom allocators. - // Get and maybe mutate the allocator state associated with the current RPC. - virtual RpcAllocatorState* GetRpcAllocatorState() = 0; -}; - -// NOTE: The actual streaming object classes are provided -// as API only to support mocking. There are no implementations of -// these class interfaces in the API. -template -class ServerCallbackReader { - public: - virtual ~ServerCallbackReader() {} - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Read(Request* msg) = 0; - - protected: - template - void BindReactor(ServerReadReactor* reactor) { - reactor->InternalBindReader(this); - } -}; - -template -class ServerCallbackWriter { - public: - virtual ~ServerCallbackWriter() {} - - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Write(const Response* msg, WriteOptions options) = 0; - virtual void WriteAndFinish(const Response* msg, WriteOptions options, - Status s) { - // Default implementation that can/should be overridden - Write(msg, std::move(options)); - Finish(std::move(s)); - } - - protected: - template - void BindReactor(ServerWriteReactor* reactor) { - reactor->InternalBindWriter(this); - } -}; - -template -class ServerCallbackReaderWriter { - public: - virtual ~ServerCallbackReaderWriter() {} - - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Read(Request* msg) = 0; - virtual void Write(const Response* msg, WriteOptions options) = 0; - virtual void WriteAndFinish(const Response* msg, WriteOptions options, - Status s) { - // Default implementation that can/should be overridden - Write(msg, std::move(options)); - Finish(std::move(s)); - } - - protected: - void BindReactor(ServerBidiReactor* reactor) { - reactor->InternalBindStream(this); - } -}; - -// The following classes are the reactor interfaces that are to be implemented -// by the user, returned as the result of the method handler for a callback -// method, and activated by the call to OnStarted. The library guarantees that -// OnStarted will be called for any reactor that has been created using a -// method handler registered on a service. No operation initiation method may be -// called until after the call to OnStarted. -// Note that none of the classes are pure; all reactions have a default empty -// reaction so that the user class only needs to override those classes that it -// cares about. - -/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. template -class ServerBidiReactor : public internal::ServerReactor { - public: - ~ServerBidiReactor() = default; - - /// Do NOT call any operation initiation method (names that start with Start) - /// until after the library has called OnStarted on this object. - - /// Send any initial metadata stored in the RPC context. If not invoked, - /// any initial metadata will be passed along with the first Write or the - /// Finish (if there are no writes). - void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } - - /// Initiate a read operation. - /// - /// \param[out] req Where to eventually store the read message. Valid when - /// the library calls OnReadDone - void StartRead(Request* req) { stream_->Read(req); } - - /// Initiate a write operation. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } - - /// Initiate a write operation with specified options. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - void StartWrite(const Response* resp, WriteOptions options) { - stream_->Write(resp, std::move(options)); - } - - /// Initiate a write operation with specified options and final RPC Status, - /// which also causes any trailing metadata for this RPC to be sent out. - /// StartWriteAndFinish is like merging StartWriteLast and Finish into a - /// single step. A key difference, though, is that this operation doesn't have - /// an OnWriteDone reaction - it is considered complete only when OnDone is - /// available. An RPC can either have StartWriteAndFinish or Finish, but not - /// both. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until Onone, at which point the application - /// regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - /// \param[in] s The status outcome of this RPC - void StartWriteAndFinish(const Response* resp, WriteOptions options, - Status s) { - stream_->WriteAndFinish(resp, std::move(options), std::move(s)); - } - - /// Inform system of a planned write operation with specified options, but - /// allow the library to schedule the actual write coalesced with the writing - /// of trailing metadata (which takes place on a Finish call). - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - void StartWriteLast(const Response* resp, WriteOptions options) { - StartWrite(resp, std::move(options.set_last_message())); - } - - /// Indicate that the stream is to be finished and the trailing metadata and - /// RPC status are to be sent. Every RPC MUST be finished using either Finish - /// or StartWriteAndFinish (but not both), even if the RPC is already - /// cancelled. - /// - /// \param[in] s The status outcome of this RPC - void Finish(Status s) { stream_->Finish(std::move(s)); } - - /// Notify the application that a streaming RPC has started and that it is now - /// ok to call any operation initiation method. An RPC is considered started - /// after the server has received all initial metadata from the client, which - /// is a result of the client calling StartCall(). - /// - /// \param[in] context The context object now associated with this RPC - virtual void OnStarted(::grpc_impl::ServerContext* context) {} - - /// Notifies the application that an explicit StartSendInitialMetadata - /// operation completed. Not used when the sending of initial metadata - /// piggybacks onto the first write. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnSendInitialMetadataDone(bool ok) {} - - /// Notifies the application that a StartRead operation completed. - /// - /// \param[in] ok Was it successful? If false, no further read-side operation - /// will succeed. - virtual void OnReadDone(bool ok) {} - - /// Notifies the application that a StartWrite (or StartWriteLast) operation - /// completed. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnWriteDone(bool ok) {} - - /// Notifies the application that all operations associated with this RPC - /// have completed. This is an override (from the internal base class) but not - /// final, so derived classes should override it if they want to take action. - void OnDone() override {} - - /// Notifies the application that this RPC has been cancelled. This is an - /// override (from the internal base class) but not final, so derived classes - /// should override it if they want to take action. - void OnCancel() override {} - - private: - friend class ServerCallbackReaderWriter; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindStream( - ServerCallbackReaderWriter* stream) { - stream_ = stream; - } +using ServerReadReactor = + ::grpc_impl::experimental::ServerReadReactor; - ServerCallbackReaderWriter* stream_; -}; - -/// \a ServerReadReactor is the interface for a client-streaming RPC. template -class ServerReadReactor : public internal::ServerReactor { - public: - ~ServerReadReactor() = default; - - /// The following operation initiations are exactly like ServerBidiReactor. - void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } - void StartRead(Request* req) { reader_->Read(req); } - void Finish(Status s) { reader_->Finish(std::move(s)); } - - /// Similar to ServerBidiReactor::OnStarted, except that this also provides - /// the response object that the stream fills in before calling Finish. - /// (It must be filled in if status is OK, but it may be filled in otherwise.) - /// - /// \param[in] context The context object now associated with this RPC - /// \param[in] resp The response object to be used by this RPC - virtual void OnStarted(::grpc_impl::ServerContext* context, Response* resp) {} - - /// The following notifications are exactly like ServerBidiReactor. - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - void OnDone() override {} - void OnCancel() override {} - - private: - friend class ServerCallbackReader; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindReader(ServerCallbackReader* reader) { - reader_ = reader; - } +using ServerWriteReactor = + ::grpc_impl::experimental::ServerWriteReactor; - ServerCallbackReader* reader_; -}; - -/// \a ServerWriteReactor is the interface for a server-streaming RPC. template -class ServerWriteReactor : public internal::ServerReactor { - public: - ~ServerWriteReactor() = default; - - /// The following operation initiations are exactly like ServerBidiReactor. - void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } - void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } - void StartWrite(const Response* resp, WriteOptions options) { - writer_->Write(resp, std::move(options)); - } - void StartWriteAndFinish(const Response* resp, WriteOptions options, - Status s) { - writer_->WriteAndFinish(resp, std::move(options), std::move(s)); - } - void StartWriteLast(const Response* resp, WriteOptions options) { - StartWrite(resp, std::move(options.set_last_message())); - } - void Finish(Status s) { writer_->Finish(std::move(s)); } - - /// Similar to ServerBidiReactor::OnStarted, except that this also provides - /// the request object sent by the client. - /// - /// \param[in] context The context object now associated with this RPC - /// \param[in] req The request object sent by the client - virtual void OnStarted(::grpc_impl::ServerContext* context, - const Request* req) {} - - /// The following notifications are exactly like ServerBidiReactor. - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - void OnDone() override {} - void OnCancel() override {} +using ServerBidiReactor = + ::grpc_impl::experimental::ServerBidiReactor; - private: - friend class ServerCallbackWriter; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindWriter(ServerCallbackWriter* writer) { - writer_ = writer; - } - - ServerCallbackWriter* writer_; -}; +typedef ::grpc_impl::experimental::ServerCallbackRpcController + ServerCallbackRpcController; } // namespace experimental - -namespace internal { - -template -class UnimplementedReadReactor - : public experimental::ServerReadReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*, Response*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class UnimplementedWriteReactor - : public experimental::ServerWriteReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*, const Request*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class UnimplementedBidiReactor - : public experimental::ServerBidiReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class CallbackUnaryHandler : public MethodHandler { - public: - CallbackUnaryHandler( - std::function - func) - : func_(func) {} - - void SetMessageAllocator( - experimental::MessageAllocator* allocator) { - allocator_ = allocator; - } - - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a controller structure (that includes request/response) - g_core_codegen_interface->grpc_call_ref(param.call->call()); - auto* allocator_state = - static_cast*>( - param.internal_data); - auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) - ServerCallbackRpcControllerImpl(param.server_context, param.call, - allocator_state, - std::move(param.call_requester)); - Status status = param.status; - if (status.ok()) { - // Call the actual function handler and expect the user to call finish - CatchingCallback(func_, param.server_context, controller->request(), - controller->response(), controller); - } else { - // if deserialization failed, we need to fail the call - controller->Finish(status); - } - } - - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, - void** handler_data) final { - ByteBuffer buf; - buf.set_buffer(req); - RequestType* request = nullptr; - experimental::MessageHolder* allocator_state = - nullptr; - if (allocator_ != nullptr) { - allocator_state = allocator_->AllocateMessages(); - } else { - allocator_state = new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(DefaultMessageHolder))) - DefaultMessageHolder(); - } - *handler_data = allocator_state; - request = allocator_state->request(); - *status = SerializationTraits::Deserialize(&buf, request); - buf.Release(); - if (status->ok()) { - return request; - } - // Clean up on deserialization failure. - allocator_state->Release(); - return nullptr; - } - - private: - std::function - func_; - experimental::MessageAllocator* allocator_ = - nullptr; - - // The implementation class of ServerCallbackRpcController is a private member - // of CallbackUnaryHandler since it is never exposed anywhere, and this allows - // it to take advantage of CallbackUnaryHandler's friendships. - class ServerCallbackRpcControllerImpl - : public experimental::ServerCallbackRpcController { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (s.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(response())); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - } - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata(std::function f) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 - // and if performance of this operation matters - meta_tag_.Set(call_.call(), - [this, f](bool ok) { - f(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - // Neither SetCancelCallback nor ClearCancelCallback should affect the - // callbacks_outstanding_ count since they are paired and both must precede - // the invocation of Finish (if they are used at all) - void SetCancelCallback(std::function callback) override { - ctx_->SetCancelCallback(std::move(callback)); - } - - void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } - - experimental::RpcAllocatorState* GetRpcAllocatorState() override { - return allocator_state_; - } - - private: - friend class CallbackUnaryHandler; - - ServerCallbackRpcControllerImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - experimental::MessageHolder* allocator_state, - std::function call_requester) - : ctx_(ctx), - call_(*call), - allocator_state_(allocator_state), - call_requester_(std::move(call_requester)) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); - } - - const RequestType* request() { return allocator_state_->request(); } - ResponseType* response() { return allocator_state_->response(); } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - allocator_state_->Release(); - this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - experimental::MessageHolder* const - allocator_state_; - std::function call_requester_; - std::atomic callbacks_outstanding_{ - 2}; // reserve for Finish and CompletionOp - }; -}; - -template -class CallbackClientStreamingHandler : public MethodHandler { - public: - CallbackClientStreamingHandler( - std::function< - experimental::ServerReadReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a reader structure (that includes response) - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerReadReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerReadReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedReadReactor; - } - - auto* reader = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackReaderImpl))) - ServerCallbackReaderImpl(param.server_context, param.call, - std::move(param.call_requester), reactor); - - reader->BindReactor(reactor); - reactor->OnStarted(param.server_context, reader->response()); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - reader->MaybeDone(); - } - - private: - std::function*()> - func_; - - class ServerCallbackReaderImpl - : public experimental::ServerCallbackReader { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (s.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(&resp_)); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - } - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Read(RequestType* req) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - read_ops_.RecvMessage(req); - call_.PerformOps(&read_ops_); - } - - private: - friend class CallbackClientStreamingHandler; - - ServerCallbackReaderImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - std::function call_requester, - experimental::ServerReadReactor* reactor) - : ctx_(ctx), - call_(*call), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeDone(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - } - - ~ServerCallbackReaderImpl() {} - - ResponseType* response() { return &resp_; } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackReaderImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - ResponseType resp_; - std::function call_requester_; - experimental::ServerReadReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -template -class CallbackServerStreamingHandler : public MethodHandler { - public: - CallbackServerStreamingHandler( - std::function< - experimental::ServerWriteReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a writer structure - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerWriteReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerWriteReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedWriteReactor; - } - - auto* writer = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackWriterImpl))) - ServerCallbackWriterImpl(param.server_context, param.call, - static_cast(param.request), - std::move(param.call_requester), reactor); - writer->BindReactor(reactor); - reactor->OnStarted(param.server_context, writer->request()); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - writer->MaybeDone(); - } - - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, - void** handler_data) final { - ByteBuffer buf; - buf.set_buffer(req); - auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(RequestType))) RequestType(); - *status = SerializationTraits::Deserialize(&buf, request); - buf.Release(); - if (status->ok()) { - return request; - } - request->~RequestType(); - return nullptr; - } - - private: - std::function*()> - func_; - - class ServerCallbackWriterImpl - : public experimental::ServerCallbackWriter { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - finish_ops_.set_core_cq_tag(&finish_tag_); - - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - write_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WriteAndFinish(const ResponseType* resp, WriteOptions options, - Status s) override { - // This combines the write into the finish callback - // Don't send any message if the status is bad - if (s.ok()) { - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); - } - Finish(std::move(s)); - } - - private: - friend class CallbackServerStreamingHandler; - - ServerCallbackWriterImpl( - ::grpc_impl::ServerContext* ctx, Call* call, const RequestType* req, - std::function call_requester, - experimental::ServerWriteReactor* reactor) - : ctx_(ctx), - call_(*call), - req_(req), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeDone(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - } - ~ServerCallbackWriterImpl() { req_->~RequestType(); } - - const RequestType* request() { return req_; } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackWriterImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet write_ops_; - CallbackWithSuccessTag write_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - const RequestType* req_; - std::function call_requester_; - experimental::ServerWriteReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -template -class CallbackBidiHandler : public MethodHandler { - public: - CallbackBidiHandler( - std::function< - experimental::ServerBidiReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerBidiReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerBidiReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedBidiReactor; - } - - auto* stream = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) - ServerCallbackReaderWriterImpl(param.server_context, param.call, - std::move(param.call_requester), - reactor); - - stream->BindReactor(reactor); - reactor->OnStarted(param.server_context); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - stream->MaybeDone(); - } - - private: - std::function*()> - func_; - - class ServerCallbackReaderWriterImpl - : public experimental::ServerCallbackReaderWriter { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - finish_ops_.set_core_cq_tag(&finish_tag_); - - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - write_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WriteAndFinish(const ResponseType* resp, WriteOptions options, - Status s) override { - // Don't send any message if the status is bad - if (s.ok()) { - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); - } - Finish(std::move(s)); - } - - void Read(RequestType* req) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - read_ops_.RecvMessage(req); - call_.PerformOps(&read_ops_); - } - - private: - friend class CallbackBidiHandler; - - ServerCallbackReaderWriterImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - std::function call_requester, - experimental::ServerBidiReactor* reactor) - : ctx_(ctx), - call_(*call), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeDone(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeDone(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - } - ~ServerCallbackReaderWriterImpl() {} - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet write_ops_; - CallbackWithSuccessTag write_tag_; - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - std::function call_requester_; - experimental::ServerBidiReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -} // namespace internal - } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/server_callback_impl.h b/include/grpcpp/impl/codegen/server_callback_impl.h new file mode 100644 index 00000000000..08ecdfd6497 --- /dev/null +++ b/include/grpcpp/impl/codegen/server_callback_impl.h @@ -0,0 +1,1186 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H +#define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +// Declare base class of all reactors as internal +namespace internal { + +// Forward declarations +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; + +class ServerReactor { + public: + virtual ~ServerReactor() = default; + virtual void OnDone() = 0; + virtual void OnCancel() = 0; + + private: + friend class ::grpc_impl::ServerContext; + template + friend class CallbackClientStreamingHandler; + template + friend class CallbackServerStreamingHandler; + template + friend class CallbackBidiHandler; + + // The ServerReactor is responsible for tracking when it is safe to call + // OnCancel. This function should not be called until after OnStarted is done + // and the RPC has completed with a cancellation. This is tracked by counting + // how many of these conditions have been met and calling OnCancel when none + // remain unmet. + + void MaybeCallOnCancel() { + if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + OnCancel(); + } + } + + std::atomic on_cancel_conditions_remaining_{2}; +}; + +template +class DefaultMessageHolder + : public ::grpc::experimental::MessageHolder { + public: + DefaultMessageHolder() { + this->set_request(&request_obj_); + this->set_response(&response_obj_); + } + void Release() override { + // the object is allocated in the call arena. + this->~DefaultMessageHolder(); + } + + private: + Request request_obj_; + Response response_obj_; +}; + +} // namespace internal + +namespace experimental { + +// Forward declarations +template +class ServerReadReactor; +template +class ServerWriteReactor; +template +class ServerBidiReactor; + +// For unary RPCs, the exposed controller class is only an interface +// and the actual implementation is an internal class. +class ServerCallbackRpcController { + public: + virtual ~ServerCallbackRpcController() = default; + + // The method handler must call this function when it is done so that + // the library knows to free its resources + virtual void Finish(::grpc::Status s) = 0; + + // Allow the method handler to push out the initial metadata before + // the response and status are ready + virtual void SendInitialMetadata(std::function) = 0; + + /// SetCancelCallback passes in a callback to be called when the RPC is + /// canceled for whatever reason (streaming calls have OnCancel instead). This + /// is an advanced and uncommon use with several important restrictions. This + /// function may not be called more than once on the same RPC. + /// + /// If code calls SetCancelCallback on an RPC, it must also call + /// ClearCancelCallback before calling Finish on the RPC controller. That + /// method makes sure that no cancellation callback is executed for this RPC + /// beyond the point of its return. ClearCancelCallback may be called even if + /// SetCancelCallback was not called for this RPC, and it may be called + /// multiple times. It _must_ be called if SetCancelCallback was called for + /// this RPC. + /// + /// The callback should generally be lightweight and nonblocking and primarily + /// concerned with clearing application state related to the RPC or causing + /// operations (such as cancellations) to happen on dependent RPCs. + /// + /// If the RPC is already canceled at the time that SetCancelCallback is + /// called, the callback is invoked immediately. + /// + /// The cancellation callback may be executed concurrently with the method + /// handler that invokes it but will certainly not issue or execute after the + /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the + /// callback is already executing, the callback will complete its execution + /// before ClearCancelCallback takes effect. + /// + /// To preserve the orderings described above, the callback may be called + /// under a lock that is also used for ClearCancelCallback and + /// ServerContext::IsCancelled, so the callback CANNOT call either of those + /// operations on this RPC or any other function that causes those operations + /// to be called before the callback completes. + virtual void SetCancelCallback(std::function callback) = 0; + virtual void ClearCancelCallback() = 0; + + // NOTE: This is an API for advanced users who need custom allocators. + // Get and maybe mutate the allocator state associated with the current RPC. + virtual grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() = 0; +}; + +// NOTE: The actual streaming object classes are provided +// as API only to support mocking. There are no implementations of +// these class interfaces in the API. +template +class ServerCallbackReader { + public: + virtual ~ServerCallbackReader() {} + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + + protected: + template + void BindReactor(ServerReadReactor* reactor) { + reactor->InternalBindReader(this); + } +}; + +template +class ServerCallbackWriter { + public: + virtual ~ServerCallbackWriter() {} + + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Write(const Response* msg, ::grpc::WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, ::grpc::WriteOptions options, + ::grpc::Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + template + void BindReactor(ServerWriteReactor* reactor) { + reactor->InternalBindWriter(this); + } +}; + +template +class ServerCallbackReaderWriter { + public: + virtual ~ServerCallbackReaderWriter() {} + + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + virtual void Write(const Response* msg, ::grpc::WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, ::grpc::WriteOptions options, + ::grpc::Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + void BindReactor(ServerBidiReactor* reactor) { + reactor->InternalBindStream(this); + } +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user, returned as the result of the method handler for a callback +// method, and activated by the call to OnStarted. The library guarantees that +// OnStarted will be called for any reactor that has been created using a +// method handler registered on a service. No operation initiation method may be +// called until after the call to OnStarted. +// Note that none of the classes are pure; all reactions have a default empty +// reaction so that the user class only needs to override those classes that it +// cares about. + +/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. +template +class ServerBidiReactor : public internal::ServerReactor { + public: + ~ServerBidiReactor() = default; + + /// Do NOT call any operation initiation method (names that start with Start) + /// until after the library has called OnStarted on this object. + + /// Send any initial metadata stored in the RPC context. If not invoked, + /// any initial metadata will be passed along with the first Write or the + /// Finish (if there are no writes). + void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } + + /// Initiate a read operation. + /// + /// \param[out] req Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Request* req) { stream_->Read(req); } + + /// Initiate a write operation. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + void StartWrite(const Response* resp) { + StartWrite(resp, ::grpc::WriteOptions()); + } + + /// Initiate a write operation with specified options. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Response* resp, ::grpc::WriteOptions options) { + stream_->Write(resp, std::move(options)); + } + + /// Initiate a write operation with specified options and final RPC Status, + /// which also causes any trailing metadata for this RPC to be sent out. + /// StartWriteAndFinish is like merging StartWriteLast and Finish into a + /// single step. A key difference, though, is that this operation doesn't have + /// an OnWriteDone reaction - it is considered complete only when OnDone is + /// available. An RPC can either have StartWriteAndFinish or Finish, but not + /// both. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until Onone, at which point the application + /// regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + /// \param[in] s The status outcome of this RPC + void StartWriteAndFinish(const Response* resp, ::grpc::WriteOptions options, + ::grpc::Status s) { + stream_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + + /// Inform system of a planned write operation with specified options, but + /// allow the library to schedule the actual write coalesced with the writing + /// of trailing metadata (which takes place on a Finish call). + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + + /// Indicate that the stream is to be finished and the trailing metadata and + /// RPC status are to be sent. Every RPC MUST be finished using either Finish + /// or StartWriteAndFinish (but not both), even if the RPC is already + /// cancelled. + /// + /// \param[in] s The status outcome of this RPC + void Finish(::grpc::Status s) { stream_->Finish(std::move(s)); } + + /// Notify the application that a streaming RPC has started and that it is now + /// ok to call any operation initiation method. An RPC is considered started + /// after the server has received all initial metadata from the client, which + /// is a result of the client calling StartCall(). + /// + /// \param[in] context The context object now associated with this RPC + virtual void OnStarted(::grpc_impl::ServerContext* context) {} + + /// Notifies the application that an explicit StartSendInitialMetadata + /// operation completed. Not used when the sending of initial metadata + /// piggybacks onto the first write. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnSendInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite (or StartWriteLast) operation + /// completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that all operations associated with this RPC + /// have completed. This is an override (from the internal base class) but not + /// final, so derived classes should override it if they want to take action. + void OnDone() override {} + + /// Notifies the application that this RPC has been cancelled. This is an + /// override (from the internal base class) but not final, so derived classes + /// should override it if they want to take action. + void OnCancel() override {} + + private: + friend class ServerCallbackReaderWriter; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindStream( + ServerCallbackReaderWriter* stream) { + stream_ = stream; + } + + ServerCallbackReaderWriter* stream_; +}; + +/// \a ServerReadReactor is the interface for a client-streaming RPC. +template +class ServerReadReactor : public internal::ServerReactor { + public: + ~ServerReadReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } + void StartRead(Request* req) { reader_->Read(req); } + void Finish(::grpc::Status s) { reader_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the response object that the stream fills in before calling Finish. + /// (It must be filled in if status is OK, but it may be filled in otherwise.) + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] resp The response object to be used by this RPC + virtual void OnStarted(::grpc_impl::ServerContext* context, Response* resp) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackReader; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindReader(ServerCallbackReader* reader) { + reader_ = reader; + } + + ServerCallbackReader* reader_; +}; + +/// \a ServerWriteReactor is the interface for a server-streaming RPC. +template +class ServerWriteReactor : public internal::ServerReactor { + public: + ~ServerWriteReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } + void StartWrite(const Response* resp) { + StartWrite(resp, ::grpc::WriteOptions()); + } + void StartWrite(const Response* resp, ::grpc::WriteOptions options) { + writer_->Write(resp, std::move(options)); + } + void StartWriteAndFinish(const Response* resp, ::grpc::WriteOptions options, + ::grpc::Status s) { + writer_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + void Finish(::grpc::Status s) { writer_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the request object sent by the client. + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] req The request object sent by the client + virtual void OnStarted(::grpc_impl::ServerContext* context, + const Request* req) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackWriter; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindWriter(ServerCallbackWriter* writer) { + writer_ = writer; + } + + ServerCallbackWriter* writer_; +}; + +} // namespace experimental + +namespace internal { + +template +class UnimplementedReadReactor + : public experimental::ServerReadReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*, Response*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedWriteReactor + : public experimental::ServerWriteReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*, const Request*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedBidiReactor + : public experimental::ServerBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class CallbackUnaryHandler : public grpc::internal::MethodHandler { + public: + CallbackUnaryHandler( + std::function + func) + : func_(func) {} + + void SetMessageAllocator( + ::grpc::experimental::MessageAllocator* + allocator) { + allocator_ = allocator; + } + + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a controller structure (that includes request/response) + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + auto* allocator_state = static_cast< + grpc::experimental::MessageHolder*>( + param.internal_data); + auto* controller = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) + ServerCallbackRpcControllerImpl(param.server_context, param.call, + allocator_state, + std::move(param.call_requester)); + ::grpc::Status status = param.status; + if (status.ok()) { + // Call the actual function handler and expect the user to call finish + grpc::internal::CatchingCallback(func_, param.server_context, + controller->request(), + controller->response(), controller); + } else { + // if deserialization failed, we need to fail the call + controller->Finish(status); + } + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, + ::grpc::Status* status, void** handler_data) final { + grpc::ByteBuffer buf; + buf.set_buffer(req); + RequestType* request = nullptr; + ::grpc::experimental::MessageHolder* + allocator_state = nullptr; + if (allocator_ != nullptr) { + allocator_state = allocator_->AllocateMessages(); + } else { + allocator_state = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(DefaultMessageHolder))) + DefaultMessageHolder(); + } + *handler_data = allocator_state; + request = allocator_state->request(); + *status = + ::grpc::SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + // Clean up on deserialization failure. + allocator_state->Release(); + return nullptr; + } + + private: + std::function + func_; + grpc::experimental::MessageAllocator* allocator_ = + nullptr; + + // The implementation class of ServerCallbackRpcController is a private member + // of CallbackUnaryHandler since it is never exposed anywhere, and this allows + // it to take advantage of CallbackUnaryHandler's friendships. + class ServerCallbackRpcControllerImpl + : public experimental::ServerCallbackRpcController { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(response())); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata(std::function f) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 + // and if performance of this operation matters + meta_tag_.Set(call_.call(), + [this, f](bool ok) { + f(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + // Neither SetCancelCallback nor ClearCancelCallback should affect the + // callbacks_outstanding_ count since they are paired and both must precede + // the invocation of Finish (if they are used at all) + void SetCancelCallback(std::function callback) override { + ctx_->SetCancelCallback(std::move(callback)); + } + + void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } + + grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() override { + return allocator_state_; + } + + private: + friend class CallbackUnaryHandler; + + ServerCallbackRpcControllerImpl( + ServerContext* ctx, ::grpc::internal::Call* call, + ::grpc::experimental::MessageHolder* + allocator_state, + std::function call_requester) + : ctx_(ctx), + call_(*call), + allocator_state_(allocator_state), + call_requester_(std::move(call_requester)) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); + } + + const RequestType* request() { return allocator_state_->request(); } + ResponseType* response() { return allocator_state_->response(); } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + allocator_state_->Release(); + this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + grpc::experimental::MessageHolder* const + allocator_state_; + std::function call_requester_; + std::atomic callbacks_outstanding_{ + 2}; // reserve for Finish and CompletionOp + }; +}; + +template +class CallbackClientStreamingHandler : public grpc::internal::MethodHandler { + public: + CallbackClientStreamingHandler( + std::function< + experimental::ServerReadReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a reader structure (that includes response) + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerReadReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerReadReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedReadReactor; + } + + auto* reader = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderImpl))) + ServerCallbackReaderImpl(param.server_context, param.call, + std::move(param.call_requester), reactor); + + reader->BindReactor(reactor); + reactor->OnStarted(param.server_context, reader->response()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + reader->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderImpl + : public experimental::ServerCallbackReader { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(&resp_)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Read(RequestType* req) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackClientStreamingHandler; + + ServerCallbackReaderImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + std::function call_requester, + experimental::ServerReadReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + ~ServerCallbackReaderImpl() {} + + ResponseType* response() { return &resp_; } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + ResponseType resp_; + std::function call_requester_; + experimental::ServerReadReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackServerStreamingHandler : public grpc::internal::MethodHandler { + public: + CallbackServerStreamingHandler( + std::function< + experimental::ServerWriteReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a writer structure + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerWriteReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerWriteReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedWriteReactor; + } + + auto* writer = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackWriterImpl))) + ServerCallbackWriterImpl(param.server_context, param.call, + static_cast(param.request), + std::move(param.call_requester), reactor); + writer->BindReactor(reactor); + reactor->OnStarted(param.server_context, writer->request()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + writer->MaybeDone(); + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, + ::grpc::Status* status, void** handler_data) final { + ::grpc::ByteBuffer buf; + buf.set_buffer(req); + auto* request = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(RequestType))) RequestType(); + *status = + ::grpc::SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + request->~RequestType(); + return nullptr; + } + + private: + std::function*()> + func_; + + class ServerCallbackWriterImpl + : public experimental::ServerCallbackWriter { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, + ::grpc::WriteOptions options) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, ::grpc::WriteOptions options, + ::grpc::Status s) override { + // This combines the write into the finish callback + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); + } + + private: + friend class CallbackServerStreamingHandler; + + ServerCallbackWriterImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + const RequestType* req, std::function call_requester, + experimental::ServerWriteReactor* reactor) + : ctx_(ctx), + call_(*call), + req_(req), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + } + ~ServerCallbackWriterImpl() { req_->~RequestType(); } + + const RequestType* request() { return req_; } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackWriterImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + const RequestType* req_; + std::function call_requester_; + experimental::ServerWriteReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackBidiHandler : public grpc::internal::MethodHandler { + public: + CallbackBidiHandler( + std::function< + experimental::ServerBidiReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerBidiReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerBidiReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedBidiReactor; + } + + auto* stream = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) + ServerCallbackReaderWriterImpl(param.server_context, param.call, + std::move(param.call_requester), + reactor); + + stream->BindReactor(reactor); + reactor->OnStarted(param.server_context); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + stream->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderWriterImpl + : public experimental::ServerCallbackReaderWriter { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, + ::grpc::WriteOptions options) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, ::grpc::WriteOptions options, + ::grpc::Status s) override { + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); + } + + void Read(RequestType* req) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackBidiHandler; + + ServerCallbackReaderWriterImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + std::function call_requester, + experimental::ServerBidiReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + ~ServerCallbackReaderWriterImpl() {} + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + std::function call_requester_; + experimental::ServerBidiReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +} // namespace internal + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H diff --git a/include/grpcpp/impl/codegen/server_context_impl.h b/include/grpcpp/impl/codegen/server_context_impl.h index 9497735eacc..72137f153b1 100644 --- a/include/grpcpp/impl/codegen/server_context_impl.h +++ b/include/grpcpp/impl/codegen/server_context_impl.h @@ -44,10 +44,6 @@ namespace grpc_impl { class ClientContext; class CompletionQueue; class Server; -} // namespace grpc_impl -namespace grpc { -class GenericServerContext; -class ServerInterface; template class ServerAsyncReader; template @@ -62,14 +58,6 @@ template class ServerWriter; namespace internal { -template -class ServerReaderWriterBody; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; template class BidiStreamingHandler; template @@ -80,12 +68,28 @@ template class CallbackServerStreamingHandler; template class CallbackBidiHandler; +template +class ServerReaderWriterBody; +class ServerReactor; +} // namespace internal + +} // namespace grpc_impl +namespace grpc { +class GenericServerContext; +class ServerInterface; + +namespace internal { +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class RpcMethodHandler; template class TemplatedBidiStreamingHandler; template class ErrorMethodHandler; class Call; -class ServerReactor; } // namespace internal class ServerInterface; @@ -275,19 +279,19 @@ class ServerContext { friend class ::grpc::ServerInterface; friend class ::grpc_impl::Server; template - friend class ::grpc::ServerAsyncReader; + friend class ::grpc_impl::ServerAsyncReader; template - friend class ::grpc::ServerAsyncWriter; + friend class ::grpc_impl::ServerAsyncWriter; template - friend class ::grpc::ServerAsyncResponseWriter; + friend class ::grpc_impl::ServerAsyncResponseWriter; template - friend class ::grpc::ServerAsyncReaderWriter; + friend class ::grpc_impl::ServerAsyncReaderWriter; template - friend class ::grpc::ServerReader; + friend class ::grpc_impl::ServerReader; template - friend class ::grpc::ServerWriter; + friend class ::grpc_impl::ServerWriter; template - friend class ::grpc::internal::ServerReaderWriterBody; + friend class ::grpc_impl::internal::ServerReaderWriterBody; template friend class ::grpc::internal::RpcMethodHandler; template @@ -297,13 +301,13 @@ class ServerContext { template friend class ::grpc::internal::TemplatedBidiStreamingHandler; template - friend class ::grpc::internal::CallbackUnaryHandler; + friend class ::grpc_impl::internal::CallbackUnaryHandler; template - friend class ::grpc::internal::CallbackClientStreamingHandler; + friend class ::grpc_impl::internal::CallbackClientStreamingHandler; template - friend class ::grpc::internal::CallbackServerStreamingHandler; + friend class ::grpc_impl::internal::CallbackServerStreamingHandler; template - friend class ::grpc::internal::CallbackBidiHandler; + friend class ::grpc_impl::internal::CallbackBidiHandler; template <::grpc::StatusCode code> friend class ::grpc::internal::ErrorMethodHandler; friend class ::grpc_impl::ClientContext; @@ -317,7 +321,7 @@ class ServerContext { void BeginCompletionOp(::grpc::internal::Call* call, std::function callback, - ::grpc::internal::ServerReactor* reactor); + ::grpc_impl::internal::ServerReactor* reactor); /// Return the tag queued by BeginCompletionOp() ::grpc::internal::CompletionQueueTag* GetCompletionOpTag(); diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 4109ee1b504..f13dfb99fa0 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -149,8 +149,9 @@ class Service { void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context, Message* request, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) { // Typecast the index to size_t for indexing into a vector // while preserving the API that existed before a compiler // warning was first seen (grpc/grpc#11664) @@ -160,8 +161,9 @@ class Service { } void RequestAsyncClientStreaming( int index, ::grpc_impl::ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); @@ -169,16 +171,18 @@ class Service { template void RequestAsyncServerStreaming( int index, ::grpc_impl::ServerContext* context, Message* request, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncBidiStreaming( int index, ::grpc_impl::ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 9d030a13a71..cd447d7c5a5 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -19,918 +19,42 @@ #ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H #define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -namespace internal { -/// Common interface for all synchronous client side streaming. -class ClientStreamingInterface { - public: - virtual ~ClientStreamingInterface() {} - - /// Block waiting until the stream finishes and a final status of the call is - /// available. - /// - /// It is appropriate to call this method when both: - /// * the calling code (client-side) has no more message to send - /// (this can be declared implicitly by calling this method, or - /// explicitly through an earlier call to WritesDone method of the - /// class in use, e.g. \a ClientWriterInterface::WritesDone or - /// \a ClientReaderWriterInterface::WritesDone). - /// * there are no more messages to be received from the server (which can - /// be known implicitly, or explicitly from an earlier call to \a - /// ReaderInterface::Read that returned "false"). - /// - /// This function will return either: - /// - when all incoming messages have been read and the server has - /// returned status. - /// - when the server has returned a non-OK status. - /// - OR when the call failed for some reason and the library generated a - /// status. - /// - /// Return values: - /// - \a Status contains the status code, message and details for the call - /// - the \a ClientContext associated with this call is updated with - /// possible trailing metadata sent from the server. - virtual Status Finish() = 0; -}; - -/// Common interface for all synchronous server side streaming. -class ServerStreamingInterface { - public: - virtual ~ServerStreamingInterface() {} - - /// Block to send initial metadata to client. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// The initial metadata that will be sent to the client will be - /// taken from the \a ServerContext associated with the call. - virtual void SendInitialMetadata() = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. template -class ReaderInterface { - public: - virtual ~ReaderInterface() {} - - /// Get an upper bound on the next message size available for reading on this - /// stream. - virtual bool NextMessageSize(uint32_t* sz) = 0; - - /// Block to read a message and parse to \a msg. Returns \a true on success. - /// This is thread-safe with respect to \a Write or \WritesDone methods on - /// the same stream. It should not be called concurrently with another \a - /// Read on the same stream as the order of delivery will not be defined. - /// - /// \param[out] msg The read message. - /// - /// \return \a false when there will be no more incoming messages, either - /// because the other side has called \a WritesDone() or the stream has failed - /// (or been cancelled). - virtual bool Read(R* msg) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class WriterInterface { - public: - virtual ~WriterInterface() {} - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - virtual bool Write(const W& msg, WriteOptions options) = 0; - - /// Block to write \a msg to the stream with default write options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// - /// \return \a true on success, \a false when the stream has been closed. - inline bool Write(const W& msg) { return Write(msg, WriteOptions()); } - - /// Write \a msg and coalesce it with the writing of trailing metadata, using - /// WriteOptions \a options. - /// - /// For client, WriteLast is equivalent of performing Write and WritesDone in - /// a single step. \a msg and trailing metadata are coalesced and sent on wire - /// by calling this function. For server, WriteLast buffers the \a msg. - /// The writing of \a msg is held until the service handler returns, - /// where \a msg and trailing metadata are coalesced and sent on wire. - /// Note that WriteLast can only buffer \a msg up to the flow control window - /// size. If \a msg size is larger than the window size, it will be sent on - /// wire without buffering. - /// - /// \param[in] msg The message to be written to the stream. - /// \param[in] options The WriteOptions to be used to write this message. - void WriteLast(const W& msg, WriteOptions options) { - Write(msg, options.set_last_message()); - } -}; - -} // namespace internal +using ClientReaderInterface = ::grpc_impl::ClientReaderInterface; -/// Client-side interface for streaming reads of message of type \a R. template -class ClientReaderInterface : public internal::ClientStreamingInterface, - public internal::ReaderInterface { - public: - /// Block to wait for initial metadata from server. The received metadata - /// can only be accessed after this call returns. Should only be called before - /// the first read. Calling this method is optional, and if it is not called - /// the metadata will be available in ClientContext after the first read. - virtual void WaitForInitialMetadata() = 0; -}; - -namespace internal { -template -class ClientReaderFactory { - public: - template - static ClientReader* Create(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const W& request) { - return new ClientReader(channel, method, context, request); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for doing server-streaming RPCs, -/// where the stream of messages coming from the server has messages -/// of type \a R. -template -class ClientReader final : public ClientReaderInterface { - public: - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for - /// semantics. - /// - // Side effect: - /// Once complete, the initial metadata read from - /// the server will be accessible through the \a ClientContext used to - /// construct this object. - void WaitForInitialMetadata() override { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); /// status ignored - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_.max_receive_message_size(); - return true; - } - - /// See the \a ReaderInterface.Read method for semantics. - /// Side effect: - /// This also receives initial metadata from the server, if not - /// already received (if initial metadata is received, it can be then - /// accessed through the \a ClientContext associated with this call). - bool Read(R* msg) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - ops.RecvMessage(msg); - call_.PerformOps(&ops); - return cq_.Pluck(&ops) && ops.got_message; - } - - /// See the \a ClientStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// The \a ClientContext associated with this call is updated with - /// possible metadata received from the server. - Status Finish() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops; - Status status; - ops.ClientRecvStatus(context_, &status); - call_.PerformOps(&ops); - GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); - return status; - } - - private: - friend class internal::ClientReaderFactory; - ::grpc_impl::ClientContext* context_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; - - /// Block to create a stream and write the initial metadata and \a request - /// out. Note that \a context will be used to fill in custom initial - /// metadata used to send to the server when starting the call. - template - ClientReader(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const W& request) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); - ops.ClientSendClose(); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } -}; - -/// Client-side interface for streaming writes of message type \a W. +using ClientReader = ::grpc_impl::ClientReader; template -class ClientWriterInterface : public internal::ClientStreamingInterface, - public internal::WriterInterface { - public: - /// Half close writing from the client. (signal that the stream of messages - /// coming from the client is complete). - /// Blocks until currently-pending writes are completed. - /// Thread safe with respect to \a ReaderInterface::Read operations only - /// - /// \return Whether the writes were successful. - virtual bool WritesDone() = 0; -}; - -namespace internal { +using ClientWriterInterface = ::grpc_impl::ClientWriterInterface; template -class ClientWriterFactory { - public: - template - static ClientWriter* Create(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - R* response) { - return new ClientWriter(channel, method, context, response); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for doing client-streaming RPCs, -/// where the outgoing message stream coming from the client has messages of -/// type \a W. -template -class ClientWriter : public ClientWriterInterface { - public: - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for - /// semantics. - /// - // Side effect: - /// Once complete, the initial metadata read from the server will be - /// accessible through the \a ClientContext used to construct this object. - void WaitForInitialMetadata() { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); // status ignored - } - - /// See the WriterInterface.Write(const W& msg, WriteOptions options) method - /// for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call). - using ::grpc::internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - - if (options.is_last_message()) { - options.set_buffer_hint(); - ops.ClientSendClose(); - } - if (context_->initial_metadata_corked_) { - ops.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - context_->set_initial_metadata_corked(false); - } - if (!ops.SendMessagePtr(&msg, options).ok()) { - return false; - } - - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - bool WritesDone() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; - ops.ClientSendClose(); - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - /// See the ClientStreamingInterface.Finish method for semantics. - /// Side effects: - /// - Also receives initial metadata if not already received. - /// - Attempts to fill in the \a response parameter passed - /// to the constructor of this instance with the response - /// message from the server. - Status Finish() override { - Status status; - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, &status); - call_.PerformOps(&finish_ops_); - GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_)); - return status; - } - - private: - friend class internal::ClientWriterFactory; - - /// Block to create a stream (i.e. send request headers and other initial - /// metadata to the server). Note that \a context will be used to fill - /// in custom initial metadata. \a response will be filled in with the - /// single expected response message from the server upon a successful - /// call to the \a Finish method of this instance. - template - ClientWriter(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, R* response) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - - if (!context_->initial_metadata_corked_) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpGenericRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; -}; - -/// Client-side interface for bi-directional streaming with -/// client-to-server stream messages of type \a W and -/// server-to-client stream messages of type \a R. -template -class ClientReaderWriterInterface : public internal::ClientStreamingInterface, - public internal::WriterInterface, - public internal::ReaderInterface { - public: - /// Block to wait for initial metadata from server. The received metadata - /// can only be accessed after this call returns. Should only be called before - /// the first read. Calling this method is optional, and if it is not called - /// the metadata will be available in ClientContext after the first read. - virtual void WaitForInitialMetadata() = 0; - - /// Half close writing from the client. (signal that the stream of messages - /// coming from the clinet is complete). - /// Blocks until currently-pending writes are completed. - /// Thread-safe with respect to \a ReaderInterface::Read - /// - /// \return Whether the writes were successful. - virtual bool WritesDone() = 0; -}; - -namespace internal { +using ClientWriter = ::grpc_impl::ClientWriter; template -class ClientReaderWriterFactory { - public: - static ClientReaderWriter* Create( - ::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context) { - return new ClientReaderWriter(channel, method, context); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for bi-directional streaming RPCs, -/// where the outgoing message stream coming from the client has messages of -/// type \a W, and the incoming messages stream coming from the server has -/// messages of type \a R. +using ClientReaderWriterInterface = + ::grpc_impl::ClientReaderWriterInterface; template -class ClientReaderWriter final : public ClientReaderWriterInterface { - public: - /// Block waiting to read initial metadata from the server. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// Once complete, the initial metadata read from the server will be - /// accessible through the \a ClientContext used to construct this object. - void WaitForInitialMetadata() override { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); // status ignored - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_.max_receive_message_size(); - return true; - } - - /// See the \a ReaderInterface.Read method for semantics. - /// Side effect: - /// Also receives initial metadata if not already received (updates the \a - /// ClientContext associated with this call in that case). - bool Read(R* msg) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - ops.RecvMessage(msg); - call_.PerformOps(&ops); - return cq_.Pluck(&ops) && ops.got_message; - } - - /// See the \a WriterInterface.Write method for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call to fill in values). - using ::grpc::internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - - if (options.is_last_message()) { - options.set_buffer_hint(); - ops.ClientSendClose(); - } - if (context_->initial_metadata_corked_) { - ops.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - context_->set_initial_metadata_corked(false); - } - if (!ops.SendMessagePtr(&msg, options).ok()) { - return false; - } - - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - bool WritesDone() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; - ops.ClientSendClose(); - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - /// See the ClientStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible trailing metadata sent from the server. - Status Finish() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - Status status; - ops.ClientRecvStatus(context_, &status); - call_.PerformOps(&ops); - GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); - return status; - } - - private: - friend class internal::ClientReaderWriterFactory; - - ::grpc_impl::ClientContext* context_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; - - /// Block to create a stream and write the initial metadata and \a request - /// out. Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - ClientReaderWriter(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - if (!context_->initial_metadata_corked_) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } - } -}; - -/// Server-side interface for streaming reads of message of type \a R. +using ClientReaderWriter = ::grpc_impl::ClientReaderWriter; template -class ServerReaderInterface : public internal::ServerStreamingInterface, - public internal::ReaderInterface {}; - -/// Synchronous (blocking) server-side API for doing client-streaming RPCs, -/// where the incoming message stream coming from the client has messages of -/// type \a R. +using ServerReaderInterface = ::grpc_impl::ServerReaderInterface; template -class ServerReader final : public ServerReaderInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - internal::CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_->max_receive_message_size(); - return true; - } - - bool Read(R* msg) override { - internal::CallOpSet> ops; - ops.RecvMessage(msg); - call_->PerformOps(&ops); - return call_->cq()->Pluck(&ops) && ops.got_message; - } - - private: - internal::Call* const call_; - ::grpc_impl::ServerContext* const ctx_; - - template - friend class internal::ClientStreamingHandler; - - ServerReader(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} -}; - -/// Server-side interface for streaming writes of message of type \a W. +using ServerReader = ::grpc_impl::ServerReader; template -class ServerWriterInterface : public internal::ServerStreamingInterface, - public internal::WriterInterface {}; - -/// Synchronous (blocking) server-side API for doing for doing a -/// server-streaming RPCs, where the outgoing message stream coming from the -/// server has messages of type \a W. +using ServerWriterInterface = ::grpc_impl::ServerWriterInterface; template -class ServerWriter final : public ServerWriterInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. - /// Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - internal::CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - /// See the \a WriterInterface.Write method for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call to fill in values). - using internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - if (options.is_last_message()) { - options.set_buffer_hint(); - } - - if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { - return false; - } - if (!ctx_->sent_initial_metadata_) { - ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - call_->PerformOps(&ctx_->pending_ops_); - // if this is the last message we defer the pluck until AFTER we start - // the trailing md op. This prevents hangs. See - // https://github.com/grpc/grpc/issues/11546 - if (options.is_last_message()) { - ctx_->has_pending_ops_ = true; - return true; - } - ctx_->has_pending_ops_ = false; - return call_->cq()->Pluck(&ctx_->pending_ops_); - } - - private: - internal::Call* const call_; - ::grpc_impl::ServerContext* const ctx_; - - template - friend class internal::ServerStreamingHandler; - - ServerWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} -}; - -/// Server-side interface for bi-directional streaming. +using ServerWriter = ::grpc_impl::ServerWriter; template -class ServerReaderWriterInterface : public internal::ServerStreamingInterface, - public internal::WriterInterface, - public internal::ReaderInterface {}; - -/// Actual implementation of bi-directional streaming -namespace internal { -template -class ServerReaderWriterBody final { - public: - ServerReaderWriterBody(Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} - - void SendInitialMetadata() { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - bool NextMessageSize(uint32_t* sz) { - *sz = call_->max_receive_message_size(); - return true; - } - - bool Read(R* msg) { - CallOpSet> ops; - ops.RecvMessage(msg); - call_->PerformOps(&ops); - return call_->cq()->Pluck(&ops) && ops.got_message; - } - - bool Write(const W& msg, WriteOptions options) { - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { - return false; - } - if (!ctx_->sent_initial_metadata_) { - ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - call_->PerformOps(&ctx_->pending_ops_); - // if this is the last message we defer the pluck until AFTER we start - // the trailing md op. This prevents hangs. See - // https://github.com/grpc/grpc/issues/11546 - if (options.is_last_message()) { - ctx_->has_pending_ops_ = true; - return true; - } - ctx_->has_pending_ops_ = false; - return call_->cq()->Pluck(&ctx_->pending_ops_); - } - - private: - Call* const call_; - ::grpc_impl::ServerContext* const ctx_; -}; - -} // namespace internal - -/// Synchronous (blocking) server-side API for a bidirectional -/// streaming call, where the incoming message stream coming from the client has -/// messages of type \a R, and the outgoing message streaming coming from -/// the server has messages of type \a W. +using ServerReaderWriterInterface = + ::grpc_impl::ServerReaderWriterInterface; template -class ServerReaderWriter final : public ServerReaderWriterInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - bool Read(R* msg) override { return body_.Read(msg); } - - /// See the \a WriterInterface.Write(const W& msg, WriteOptions options) - /// method for semantics. - /// Side effect: - /// Also sends initial metadata if not already sent (using the \a - /// ServerContext associated with this call). - using internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - return body_.Write(msg, options); - } - - private: - internal::ServerReaderWriterBody body_; - - friend class internal::TemplatedBidiStreamingHandler, - false>; - ServerReaderWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx) {} -}; - -/// A class to represent a flow-controlled unary call. This is something -/// of a hybrid between conventional unary and streaming. This is invoked -/// through a unary call on the client side, but the server responds to it -/// as though it were a single-ping-pong streaming call. The server can use -/// the \a NextMessageSize method to determine an upper-bound on the size of -/// the message. A key difference relative to streaming: ServerUnaryStreamer -/// must have exactly 1 Read and exactly 1 Write, in that order, to function -/// correctly. Otherwise, the RPC is in error. +using ServerReaderWriter = ::grpc_impl::ServerReaderWriter; template -class ServerUnaryStreamer final - : public ServerReaderWriterInterface { - public: - /// Block to send initial metadata to client. - /// Implicit input parameter: - /// - the \a ServerContext associated with this call will be used for - /// sending initial metadata. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - /// Get an upper bound on the request message size from the client. - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a ReaderInterface::Read on the same stream since reads on - /// the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - bool Read(RequestType* request) override { - if (read_done_) { - return false; - } - read_done_ = true; - return body_.Read(request); - } - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - using internal::WriterInterface::Write; - bool Write(const ResponseType& response, WriteOptions options) override { - if (write_done_ || !read_done_) { - return false; - } - write_done_ = true; - return body_.Write(response, options); - } - - private: - internal::ServerReaderWriterBody body_; - bool read_done_; - bool write_done_; - - friend class internal::TemplatedBidiStreamingHandler< - ServerUnaryStreamer, true>; - ServerUnaryStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx), read_done_(false), write_done_(false) {} -}; - -/// A class to represent a flow-controlled server-side streaming call. -/// This is something of a hybrid between server-side and bidi streaming. -/// This is invoked through a server-side streaming call on the client side, -/// but the server responds to it as though it were a bidi streaming call that -/// must first have exactly 1 Read and then any number of Writes. +using ServerUnaryStreamer = + ::grpc_impl::ServerUnaryStreamer; template -class ServerSplitStreamer final - : public ServerReaderWriterInterface { - public: - /// Block to send initial metadata to client. - /// Implicit input parameter: - /// - the \a ServerContext associated with this call will be used for - /// sending initial metadata. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - /// Get an upper bound on the request message size from the client. - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a ReaderInterface::Read on the same stream since reads on - /// the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - bool Read(RequestType* request) override { - if (read_done_) { - return false; - } - read_done_ = true; - return body_.Read(request); - } - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - using internal::WriterInterface::Write; - bool Write(const ResponseType& response, WriteOptions options) override { - return read_done_ && body_.Write(response, options); - } - - private: - internal::ServerReaderWriterBody body_; - bool read_done_; - - friend class internal::TemplatedBidiStreamingHandler< - ServerSplitStreamer, false>; - ServerSplitStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx), read_done_(false) {} -}; +using ServerSplitStreamer = + ::grpc_impl::ServerSplitStreamer; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/sync_stream_impl.h b/include/grpcpp/impl/codegen/sync_stream_impl.h new file mode 100644 index 00000000000..dc764e0e27b --- /dev/null +++ b/include/grpcpp/impl/codegen/sync_stream_impl.h @@ -0,0 +1,944 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H +#define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +namespace internal { +/// Common interface for all synchronous client side streaming. +class ClientStreamingInterface { + public: + virtual ~ClientStreamingInterface() {} + + /// Block waiting until the stream finishes and a final status of the call is + /// available. + /// + /// It is appropriate to call this method when both: + /// * the calling code (client-side) has no more message to send + /// (this can be declared implicitly by calling this method, or + /// explicitly through an earlier call to WritesDone method of the + /// class in use, e.g. \a ClientWriterInterface::WritesDone or + /// \a ClientReaderWriterInterface::WritesDone). + /// * there are no more messages to be received from the server (which can + /// be known implicitly, or explicitly from an earlier call to \a + /// ReaderInterface::Read that returned "false"). + /// + /// This function will return either: + /// - when all incoming messages have been read and the server has + /// returned status. + /// - when the server has returned a non-OK status. + /// - OR when the call failed for some reason and the library generated a + /// status. + /// + /// Return values: + /// - \a Status contains the status code, message and details for the call + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. + virtual ::grpc::Status Finish() = 0; +}; + +/// Common interface for all synchronous server side streaming. +class ServerStreamingInterface { + public: + virtual ~ServerStreamingInterface() {} + + /// Block to send initial metadata to client. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// The initial metadata that will be sent to the client will be + /// taken from the \a ServerContext associated with the call. + virtual void SendInitialMetadata() = 0; +}; + +/// An interface that yields a sequence of messages of type \a R. +template +class ReaderInterface { + public: + virtual ~ReaderInterface() {} + + /// Get an upper bound on the next message size available for reading on this + /// stream. + virtual bool NextMessageSize(uint32_t* sz) = 0; + + /// Block to read a message and parse to \a msg. Returns \a true on success. + /// This is thread-safe with respect to \a Write or \WritesDone methods on + /// the same stream. It should not be called concurrently with another \a + /// Read on the same stream as the order of delivery will not be defined. + /// + /// \param[out] msg The read message. + /// + /// \return \a false when there will be no more incoming messages, either + /// because the other side has called \a WritesDone() or the stream has failed + /// (or been cancelled). + virtual bool Read(R* msg) = 0; +}; + +/// An interface that can be fed a sequence of messages of type \a W. +template +class WriterInterface { + public: + virtual ~WriterInterface() {} + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + virtual bool Write(const W& msg, ::grpc::WriteOptions options) = 0; + + /// Block to write \a msg to the stream with default write options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// + /// \return \a true on success, \a false when the stream has been closed. + inline bool Write(const W& msg) { return Write(msg, ::grpc::WriteOptions()); } + + /// Write \a msg and coalesce it with the writing of trailing metadata, using + /// WriteOptions \a options. + /// + /// For client, WriteLast is equivalent of performing Write and WritesDone in + /// a single step. \a msg and trailing metadata are coalesced and sent on wire + /// by calling this function. For server, WriteLast buffers the \a msg. + /// The writing of \a msg is held until the service handler returns, + /// where \a msg and trailing metadata are coalesced and sent on wire. + /// Note that WriteLast can only buffer \a msg up to the flow control window + /// size. If \a msg size is larger than the window size, it will be sent on + /// wire without buffering. + /// + /// \param[in] msg The message to be written to the stream. + /// \param[in] options The WriteOptions to be used to write this message. + void WriteLast(const W& msg, ::grpc::WriteOptions options) { + Write(msg, options.set_last_message()); + } +}; + +} // namespace internal + +/// Client-side interface for streaming reads of message of type \a R. +template +class ClientReaderInterface : public internal::ClientStreamingInterface, + public internal::ReaderInterface { + public: + /// Block to wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. + virtual void WaitForInitialMetadata() = 0; +}; + +namespace internal { +template +class ClientReaderFactory { + public: + template + static ClientReader* Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const W& request) { + return new ClientReader(channel, method, context, request); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for doing server-streaming RPCs, +/// where the stream of messages coming from the server has messages +/// of type \a R. +template +class ClientReader final : public ClientReaderInterface { + public: + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from + /// the server will be accessible through the \a ClientContext used to + /// construct this object. + void WaitForInitialMetadata() override { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); /// status ignored + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_.max_receive_message_size(); + return true; + } + + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// This also receives initial metadata from the server, if not + /// already received (if initial metadata is received, it can be then + /// accessed through the \a ClientContext associated with this call). + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ops.RecvMessage(msg); + call_.PerformOps(&ops); + return cq_.Pluck(&ops) && ops.got_message; + } + + /// See the \a ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// The \a ClientContext associated with this call is updated with + /// possible metadata received from the server. + ::grpc::Status Finish() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops; + ::grpc::Status status; + ops.ClientRecvStatus(context_, &status); + call_.PerformOps(&ops); + GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); + return status; + } + + private: + friend class internal::ClientReaderFactory; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; + + /// Block to create a stream and write the initial metadata and \a request + /// out. Note that \a context will be used to fill in custom initial + /// metadata used to send to the server when starting the call. + template + ClientReader(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); + ops.ClientSendClose(); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } +}; + +/// Client-side interface for streaming writes of message type \a W. +template +class ClientWriterInterface : public internal::ClientStreamingInterface, + public internal::WriterInterface { + public: + /// Half close writing from the client. (signal that the stream of messages + /// coming from the client is complete). + /// Blocks until currently-pending writes are completed. + /// Thread safe with respect to \a ReaderInterface::Read operations only + /// + /// \return Whether the writes were successful. + virtual bool WritesDone() = 0; +}; + +namespace internal { +template +class ClientWriterFactory { + public: + template + static ClientWriter* Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + R* response) { + return new ClientWriter(channel, method, context, response); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for doing client-streaming RPCs, +/// where the outgoing message stream coming from the client has messages of +/// type \a W. +template +class ClientWriter : public ClientWriterInterface { + public: + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from the server will be + /// accessible through the \a ClientContext used to construct this object. + void WaitForInitialMetadata() { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); // status ignored + } + + /// See the WriterInterface.Write(const W& msg, WriteOptions options) method + /// for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + + if (options.is_last_message()) { + options.set_buffer_hint(); + ops.ClientSendClose(); + } + if (context_->initial_metadata_corked_) { + ops.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + context_->set_initial_metadata_corked(false); + } + if (!ops.SendMessagePtr(&msg, options).ok()) { + return false; + } + + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + bool WritesDone() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; + ops.ClientSendClose(); + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + /// See the ClientStreamingInterface.Finish method for semantics. + /// Side effects: + /// - Also receives initial metadata if not already received. + /// - Attempts to fill in the \a response parameter passed + /// to the constructor of this instance with the response + /// message from the server. + ::grpc::Status Finish() override { + ::grpc::Status status; + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, &status); + call_.PerformOps(&finish_ops_); + GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_)); + return status; + } + + private: + friend class internal::ClientWriterFactory; + + /// Block to create a stream (i.e. send request headers and other initial + /// metadata to the server). Note that \a context will be used to fill + /// in custom initial metadata. \a response will be filled in with the + /// single expected response message from the server upon a successful + /// call to the \a Finish method of this instance. + template + ClientWriter(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, R* response) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + + if (!context_->initial_metadata_corked_) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpGenericRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; +}; + +/// Client-side interface for bi-directional streaming with +/// client-to-server stream messages of type \a W and +/// server-to-client stream messages of type \a R. +template +class ClientReaderWriterInterface : public internal::ClientStreamingInterface, + public internal::WriterInterface, + public internal::ReaderInterface { + public: + /// Block to wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. + virtual void WaitForInitialMetadata() = 0; + + /// Half close writing from the client. (signal that the stream of messages + /// coming from the clinet is complete). + /// Blocks until currently-pending writes are completed. + /// Thread-safe with respect to \a ReaderInterface::Read + /// + /// \return Whether the writes were successful. + virtual bool WritesDone() = 0; +}; + +namespace internal { +template +class ClientReaderWriterFactory { + public: + static ClientReaderWriter* Create( + ::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) { + return new ClientReaderWriter(channel, method, context); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for bi-directional streaming RPCs, +/// where the outgoing message stream coming from the client has messages of +/// type \a W, and the incoming messages stream coming from the server has +/// messages of type \a R. +template +class ClientReaderWriter final : public ClientReaderWriterInterface { + public: + /// Block waiting to read initial metadata from the server. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Once complete, the initial metadata read from the server will be + /// accessible through the \a ClientContext used to construct this object. + void WaitForInitialMetadata() override { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); // status ignored + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_.max_receive_message_size(); + return true; + } + + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// Also receives initial metadata if not already received (updates the \a + /// ClientContext associated with this call in that case). + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ops.RecvMessage(msg); + call_.PerformOps(&ops); + return cq_.Pluck(&ops) && ops.got_message; + } + + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + + if (options.is_last_message()) { + options.set_buffer_hint(); + ops.ClientSendClose(); + } + if (context_->initial_metadata_corked_) { + ops.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + context_->set_initial_metadata_corked(false); + } + if (!ops.SendMessagePtr(&msg, options).ok()) { + return false; + } + + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + bool WritesDone() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; + ops.ClientSendClose(); + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + /// See the ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. + ::grpc::Status Finish() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ::grpc::Status status; + ops.ClientRecvStatus(context_, &status); + call_.PerformOps(&ops); + GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); + return status; + } + + private: + friend class internal::ClientReaderWriterFactory; + + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; + + /// Block to create a stream and write the initial metadata and \a request + /// out. Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + ClientReaderWriter(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + if (!context_->initial_metadata_corked_) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } + } +}; + +/// Server-side interface for streaming reads of message of type \a R. +template +class ServerReaderInterface : public internal::ServerStreamingInterface, + public internal::ReaderInterface {}; + +/// Synchronous (blocking) server-side API for doing client-streaming RPCs, +/// where the incoming message stream coming from the client has messages of +/// type \a R. +template +class ServerReader final : public ServerReaderInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_->max_receive_message_size(); + return true; + } + + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> ops; + ops.RecvMessage(msg); + call_->PerformOps(&ops); + return call_->cq()->Pluck(&ops) && ops.got_message; + } + + private: + ::grpc::internal::Call* const call_; + ServerContext* const ctx_; + + template + friend class ::grpc::internal::ClientStreamingHandler; + + ServerReader(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} +}; + +/// Server-side interface for streaming writes of message of type \a W. +template +class ServerWriterInterface : public internal::ServerStreamingInterface, + public internal::WriterInterface {}; + +/// Synchronous (blocking) server-side API for doing for doing a +/// server-streaming RPCs, where the outgoing message stream coming from the +/// server has messages of type \a W. +template +class ServerWriter final : public ServerWriterInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. + /// Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + if (options.is_last_message()) { + options.set_buffer_hint(); + } + + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { + return false; + } + if (!ctx_->sent_initial_metadata_) { + ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + call_->PerformOps(&ctx_->pending_ops_); + // if this is the last message we defer the pluck until AFTER we start + // the trailing md op. This prevents hangs. See + // https://github.com/grpc/grpc/issues/11546 + if (options.is_last_message()) { + ctx_->has_pending_ops_ = true; + return true; + } + ctx_->has_pending_ops_ = false; + return call_->cq()->Pluck(&ctx_->pending_ops_); + } + + private: + ::grpc::internal::Call* const call_; + ::grpc_impl::ServerContext* const ctx_; + + template + friend class ::grpc::internal::ServerStreamingHandler; + + ServerWriter(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} +}; + +/// Server-side interface for bi-directional streaming. +template +class ServerReaderWriterInterface : public internal::ServerStreamingInterface, + public internal::WriterInterface, + public internal::ReaderInterface {}; + +/// Actual implementation of bi-directional streaming +namespace internal { +template +class ServerReaderWriterBody final { + public: + ServerReaderWriterBody(grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} + + void SendInitialMetadata() { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + grpc::internal::CallOpSet ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + bool NextMessageSize(uint32_t* sz) { + *sz = call_->max_receive_message_size(); + return true; + } + + bool Read(R* msg) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> ops; + ops.RecvMessage(msg); + call_->PerformOps(&ops); + return call_->cq()->Pluck(&ops) && ops.got_message; + } + + bool Write(const W& msg, ::grpc::WriteOptions options) { + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { + return false; + } + if (!ctx_->sent_initial_metadata_) { + ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + call_->PerformOps(&ctx_->pending_ops_); + // if this is the last message we defer the pluck until AFTER we start + // the trailing md op. This prevents hangs. See + // https://github.com/grpc/grpc/issues/11546 + if (options.is_last_message()) { + ctx_->has_pending_ops_ = true; + return true; + } + ctx_->has_pending_ops_ = false; + return call_->cq()->Pluck(&ctx_->pending_ops_); + } + + private: + grpc::internal::Call* const call_; + ::grpc_impl::ServerContext* const ctx_; +}; + +} // namespace internal + +/// Synchronous (blocking) server-side API for a bidirectional +/// streaming call, where the incoming message stream coming from the client has +/// messages of type \a R, and the outgoing message streaming coming from +/// the server has messages of type \a W. +template +class ServerReaderWriter final : public ServerReaderWriterInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + bool Read(R* msg) override { return body_.Read(msg); } + + /// See the \a WriterInterface.Write(const W& msg, WriteOptions options) + /// method for semantics. + /// Side effect: + /// Also sends initial metadata if not already sent (using the \a + /// ServerContext associated with this call). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + return body_.Write(msg, options); + } + + private: + internal::ServerReaderWriterBody body_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerReaderWriter, false>; + ServerReaderWriter(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx) {} +}; + +/// A class to represent a flow-controlled unary call. This is something +/// of a hybrid between conventional unary and streaming. This is invoked +/// through a unary call on the client side, but the server responds to it +/// as though it were a single-ping-pong streaming call. The server can use +/// the \a NextMessageSize method to determine an upper-bound on the size of +/// the message. A key difference relative to streaming: ServerUnaryStreamer +/// must have exactly 1 Read and exactly 1 Write, in that order, to function +/// correctly. Otherwise, the RPC is in error. +template +class ServerUnaryStreamer final + : public ServerReaderWriterInterface { + public: + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + /// Get an upper bound on the request message size from the client. + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a ReaderInterface::Read on the same stream since reads on + /// the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + bool Read(RequestType* request) override { + if (read_done_) { + return false; + } + read_done_ = true; + return body_.Read(request); + } + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + using internal::WriterInterface::Write; + bool Write(const ResponseType& response, + ::grpc::WriteOptions options) override { + if (write_done_ || !read_done_) { + return false; + } + write_done_ = true; + return body_.Write(response, options); + } + + private: + internal::ServerReaderWriterBody body_; + bool read_done_; + bool write_done_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerUnaryStreamer, true>; + ServerUnaryStreamer(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx), read_done_(false), write_done_(false) {} +}; + +/// A class to represent a flow-controlled server-side streaming call. +/// This is something of a hybrid between server-side and bidi streaming. +/// This is invoked through a server-side streaming call on the client side, +/// but the server responds to it as though it were a bidi streaming call that +/// must first have exactly 1 Read and then any number of Writes. +template +class ServerSplitStreamer final + : public ServerReaderWriterInterface { + public: + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + /// Get an upper bound on the request message size from the client. + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a ReaderInterface::Read on the same stream since reads on + /// the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + bool Read(RequestType* request) override { + if (read_done_) { + return false; + } + read_done_ = true; + return body_.Read(request); + } + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + using internal::WriterInterface::Write; + bool Write(const ResponseType& response, + ::grpc::WriteOptions options) override { + return read_done_ && body_.Write(response, options); + } + + private: + internal::ServerReaderWriterBody body_; + bool read_done_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerSplitStreamer, false>; + ServerSplitStreamer(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx), read_done_(false) {} +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H diff --git a/include/grpcpp/support/async_stream_impl.h b/include/grpcpp/support/async_stream_impl.h new file mode 100644 index 00000000000..cff700d3fa9 --- /dev/null +++ b/include/grpcpp/support/async_stream_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H +#define GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H diff --git a/include/grpcpp/support/async_unary_call_impl.h b/include/grpcpp/support/async_unary_call_impl.h new file mode 100644 index 00000000000..488fe87515a --- /dev/null +++ b/include/grpcpp/support/async_unary_call_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H +#define GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H diff --git a/include/grpcpp/support/client_callback_impl.h b/include/grpcpp/support/client_callback_impl.h new file mode 100644 index 00000000000..ed8df412496 --- /dev/null +++ b/include/grpcpp/support/client_callback_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H +#define GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H diff --git a/include/grpcpp/support/server_callback_impl.h b/include/grpcpp/support/server_callback_impl.h new file mode 100644 index 00000000000..a91c8141dd8 --- /dev/null +++ b/include/grpcpp/support/server_callback_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H +#define GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H diff --git a/include/grpcpp/support/sync_stream_impl.h b/include/grpcpp/support/sync_stream_impl.h new file mode 100644 index 00000000000..a00e425acfc --- /dev/null +++ b/include/grpcpp/support/sync_stream_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H +#define GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 358efe9fd79..044647d9a81 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -143,6 +143,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/client_callback.h", "grpcpp/impl/codegen/client_context.h", + "grpcpp/impl/codegen/completion_queue.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", @@ -946,11 +947,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerReadReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedReadReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerReadReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedReadReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, @@ -962,11 +964,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerWriteReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedWriteReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerWriteReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedWriteReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, @@ -978,11 +981,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerBidiReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedBidiReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerBidiReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedBidiReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } } @@ -1010,7 +1014,7 @@ void PrintHeaderServerMethodCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackUnaryHandler< " + " new ::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" @@ -1024,7 +1028,7 @@ void PrintHeaderServerMethodCallback( "void SetMessageAllocatorFor_$Method$(\n" " ::grpc::experimental::MessageAllocator< " "$RealRequest$, $RealResponse$>* allocator) {\n" - " static_cast<::grpc::internal::CallbackUnaryHandler< " + " static_cast<::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>*>(\n" " ::grpc::Service::experimental().GetHandler($Idx$))\n" " ->SetMessageAllocator(allocator);\n"); @@ -1032,21 +1036,21 @@ void PrintHeaderServerMethodCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackClientStreamingHandler< " + " new ::grpc_impl::internal::CallbackClientStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackServerStreamingHandler< " + " new ::grpc_impl::internal::CallbackServerStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackBidiHandler< " + " new ::grpc_impl::internal::CallbackBidiHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } @@ -1084,7 +1088,7 @@ void PrintHeaderServerMethodRawCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackUnaryHandler< " + " new ::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" @@ -1098,21 +1102,21 @@ void PrintHeaderServerMethodRawCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackClientStreamingHandler< " + " new ::grpc_impl::internal::CallbackClientStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackServerStreamingHandler< " + " new ::grpc_impl::internal::CallbackServerStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackBidiHandler< " + " new ::grpc_impl::internal::CallbackBidiHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } @@ -1705,7 +1709,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " ::grpc::internal::CallbackUnaryCall" + " ::grpc_impl::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); @@ -1715,7 +1719,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const ::grpc::ByteBuffer* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " ::grpc::internal::CallbackUnaryCall" + " ::grpc_impl::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); @@ -1725,7 +1729,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackUnaryFactory::Create" + " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, reactor);\n}\n\n"); @@ -1735,7 +1739,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const ::grpc::ByteBuffer* request, $Response$* response, " "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackUnaryFactory::Create" + " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, reactor);\n}\n\n"); @@ -1751,7 +1755,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, printer->Print( *vars, " return " - "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>" + "::grpc_impl::internal::ClientAsyncResponseReaderFactory< $Response$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request, $AsyncStart$);\n" @@ -1762,13 +1766,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientWriter< $Request$>* " "$ns$$Service$::Stub::$Method$Raw(" "::grpc::ClientContext* context, $Response$* response) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientWriterFactory< $Request$>::Create(" - "channel_.get(), " - "rpcmethod_$Method$_, " - "context, response);\n" - "}\n\n"); + printer->Print(*vars, + " return ::grpc_impl::internal::ClientWriterFactory< " + "$Request$>::Create(" + "channel_.get(), " + "rpcmethod_$Method$_, " + "context, response);\n" + "}\n\n"); printer->Print( *vars, @@ -1777,7 +1781,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "$Response$* response, " "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackWriterFactory< " + " ::grpc_impl::internal::ClientCallbackWriterFactory< " "$Request$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1796,7 +1800,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print( *vars, - " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>" + " return ::grpc_impl::internal::ClientAsyncWriterFactory< $Request$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, response, $AsyncStart$$AsyncCreateArgs$);\n" @@ -1808,13 +1812,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientReader< $Response$>* " "$ns$$Service$::Stub::$Method$Raw(" "::grpc::ClientContext* context, const $Request$& request) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientReaderFactory< $Response$>::Create(" - "channel_.get(), " - "rpcmethod_$Method$_, " - "context, request);\n" - "}\n\n"); + printer->Print(*vars, + " return ::grpc_impl::internal::ClientReaderFactory< " + "$Response$>::Create(" + "channel_.get(), " + "rpcmethod_$Method$_, " + "context, request);\n" + "}\n\n"); printer->Print( *vars, @@ -1823,7 +1827,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "$Request$* request, " "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackReaderFactory< " + " ::grpc_impl::internal::ClientCallbackReaderFactory< " "$Response$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1843,7 +1847,8 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print( *vars, - " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>" + " return ::grpc_impl::internal::ClientAsyncReaderFactory< " + "$Response$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request, $AsyncStart$$AsyncCreateArgs$);\n" @@ -1855,7 +1860,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientReaderWriter< $Request$, $Response$>* " "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n"); printer->Print(*vars, - " return ::grpc::internal::ClientReaderWriterFactory< " + " return ::grpc_impl::internal::ClientReaderWriterFactory< " "$Request$, $Response$>::Create(" "channel_.get(), " "rpcmethod_$Method$_, " @@ -1868,13 +1873,14 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "ClientContext* context, " "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* " "reactor) {\n"); - printer->Print(*vars, - " ::grpc::internal::ClientCallbackReaderWriterFactory< " - "$Request$,$Response$>::Create(" - "stub_->channel_.get(), " - "stub_->rpcmethod_$Method$_, " - "context, reactor);\n" - "}\n\n"); + printer->Print( + *vars, + " ::grpc_impl::internal::ClientCallbackReaderWriterFactory< " + "$Request$,$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1888,7 +1894,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print(*vars, " return " - "::grpc::internal::ClientAsyncReaderWriterFactory< " + "::grpc_impl::internal::ClientAsyncReaderWriterFactory< " "$Request$, $Response$>::Create(" "channel_.get(), cq, " "rpcmethod_$Method$_, " @@ -2279,7 +2285,8 @@ void PrintMockClientMethods(grpc_generator::Printer* printer, printer->Print( *vars, "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*" + "::grpc::ClientAsyncReaderWriterInterface<$Request$, " + "$Response$>*" "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq" "$AsyncMethodParams$));\n"); } diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 41631c794f2..e7d3df7a497 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -27,11 +27,10 @@ namespace grpc_impl { namespace { std::unique_ptr CallInternal( grpc::ChannelInterface* channel, grpc::ClientContext* context, - const grpc::string& method, grpc::CompletionQueue* cq, bool start, - void* tag) { + const grpc::string& method, CompletionQueue* cq, bool start, void* tag) { return std::unique_ptr( - grpc::internal::ClientAsyncReaderWriterFactory:: + internal::ClientAsyncReaderWriterFactory:: Create(channel, cq, grpc::internal::RpcMethod( method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING), @@ -43,14 +42,14 @@ std::unique_ptr CallInternal( // begin a call to a named method std::unique_ptr GenericStub::Call( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq, void* tag) { + CompletionQueue* cq, void* tag) { return CallInternal(channel_.get(), context, method, cq, true, tag); } // setup a call to a named method std::unique_ptr GenericStub::PrepareCall( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq) { + CompletionQueue* cq) { return CallInternal(channel_.get(), context, method, cq, false, nullptr); } @@ -59,21 +58,20 @@ std::unique_ptr GenericStub::PrepareUnaryCall(grpc::ClientContext* context, const grpc::string& method, const grpc::ByteBuffer& request, - grpc::CompletionQueue* cq) { + CompletionQueue* cq) { return std::unique_ptr( - grpc::internal::ClientAsyncResponseReaderFactory< - grpc::ByteBuffer>::Create(channel_.get(), cq, - grpc::internal::RpcMethod( - method.c_str(), - grpc::internal::RpcMethod::NORMAL_RPC), - context, request, false)); + internal::ClientAsyncResponseReaderFactory::Create( + channel_.get(), cq, + grpc::internal::RpcMethod(method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), + context, request, false)); } void GenericStub::experimental_type::UnaryCall( grpc::ClientContext* context, const grpc::string& method, const grpc::ByteBuffer* request, grpc::ByteBuffer* response, std::function on_completion) { - grpc::internal::CallbackUnaryCall( + internal::CallbackUnaryCall( stub_->channel_.get(), grpc::internal::RpcMethod(method.c_str(), grpc::internal::RpcMethod::NORMAL_RPC), @@ -82,9 +80,9 @@ void GenericStub::experimental_type::UnaryCall( void GenericStub::experimental_type::PrepareBidiStreamingCall( grpc::ClientContext* context, const grpc::string& method, - grpc::experimental::ClientBidiReactor* + experimental::ClientBidiReactor* reactor) { - grpc::internal::ClientCallbackReaderWriterFactory< + internal::ClientCallbackReaderWriterFactory< grpc::ByteBuffer, grpc::ByteBuffer>::Create(stub_->channel_.get(), grpc::internal::RpcMethod( diff --git a/src/cpp/server/async_generic_service.cc b/src/cpp/server/async_generic_service.cc index 30613768295..556447a7f40 100644 --- a/src/cpp/server/async_generic_service.cc +++ b/src/cpp/server/async_generic_service.cc @@ -24,8 +24,8 @@ namespace grpc { void AsyncGenericService::RequestCall( GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, - CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, - void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { server_->RequestAsyncGenericCall(ctx, reader_writer, call_cq, notification_cq, tag); } diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 4b926efdfe8..14a54d53ee0 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 1ba9ae1c9dc..1d68c2bdaea 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -69,14 +69,14 @@ ServerBuilder::~ServerBuilder() { } } -std::unique_ptr ServerBuilder::AddCompletionQueue( +std::unique_ptr ServerBuilder::AddCompletionQueue( bool is_frequently_polled) { - grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( + ServerCompletionQueue* cq = new ServerCompletionQueue( GRPC_CQ_NEXT, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, nullptr); cqs_.push_back(cq); - return std::unique_ptr(cq); + return std::unique_ptr(cq); } ServerBuilder& ServerBuilder::RegisterService(grpc::Service* service) { @@ -266,10 +266,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // This is different from the completion queues added to the server via // ServerBuilder's AddCompletionQueue() method (those completion queues // are in 'cqs_' member variable of ServerBuilder object) - std::shared_ptr>> - sync_server_cqs( - std::make_shared< - std::vector>>()); + std::shared_ptr>> + sync_server_cqs(std::make_shared< + std::vector>>()); bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { @@ -298,7 +297,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // Create completion queues to listen to incoming rpc requests for (int i = 0; i < sync_server_settings_.num_cqs; i++) { sync_server_cqs->emplace_back( - new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + new ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); } } diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index ba834237ae9..1e27fad3988 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -45,8 +45,7 @@ class ServerContext::CompletionOp final public: // initial refs: one in the server context, one in the cq // must ref the call before calling constructor and after deleting this - CompletionOp(::grpc::internal::Call* call, - ::grpc::internal::ServerReactor* reactor) + CompletionOp(::grpc::internal::Call* call, internal::ServerReactor* reactor) : call_(*call), reactor_(reactor), has_tag_(false), @@ -152,7 +151,7 @@ class ServerContext::CompletionOp final } ::grpc::internal::Call call_; - ::grpc::internal::ServerReactor* const reactor_; + internal::ServerReactor* const reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; @@ -294,9 +293,9 @@ void ServerContext::Clear() { } } -void ServerContext::BeginCompletionOp( - ::grpc::internal::Call* call, std::function callback, - ::grpc::internal::ServerReactor* reactor) { +void ServerContext::BeginCompletionOp(::grpc::internal::Call* call, + std::function callback, + internal::ServerReactor* reactor) { GPR_ASSERT(!completion_op_); if (rpc_info_) { rpc_info_->Ref(); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 035955023b8..34fb5bfb53f 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -336,7 +337,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, @@ -346,7 +347,7 @@ class ServiceA final { } void SetMessageAllocatorFor_MethodA1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } @@ -367,7 +368,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA2() { ::grpc::Service::experimental().MarkMethodCallback(1, - new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA2(); })); } ~ExperimentalWithCallbackMethod_MethodA2() override { @@ -379,7 +380,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA2() { - return new ::grpc::internal::UnimplementedReadReactor< + return new ::grpc_impl::internal::UnimplementedReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; template @@ -389,7 +390,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA3() { ::grpc::Service::experimental().MarkMethodCallback(2, - new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA3(); })); } ~ExperimentalWithCallbackMethod_MethodA3() override { @@ -401,7 +402,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA3() { - return new ::grpc::internal::UnimplementedWriteReactor< + return new ::grpc_impl::internal::UnimplementedWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; template @@ -411,7 +412,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA4() { ::grpc::Service::experimental().MarkMethodCallback(3, - new ::grpc::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA4(); })); } ~ExperimentalWithCallbackMethod_MethodA4() override { @@ -423,7 +424,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4() { - return new ::grpc::internal::UnimplementedBidiReactor< + return new ::grpc_impl::internal::UnimplementedBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; @@ -582,7 +583,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, @@ -607,7 +608,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA2() { ::grpc::Service::experimental().MarkMethodRawCallback(1, - new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA2(); })); } ~ExperimentalWithRawCallbackMethod_MethodA2() override { @@ -619,7 +620,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA2() { - return new ::grpc::internal::UnimplementedReadReactor< + return new ::grpc_impl::internal::UnimplementedReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -629,7 +630,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA3() { ::grpc::Service::experimental().MarkMethodRawCallback(2, - new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA3(); })); } ~ExperimentalWithRawCallbackMethod_MethodA3() override { @@ -641,7 +642,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA3() { - return new ::grpc::internal::UnimplementedWriteReactor< + return new ::grpc_impl::internal::UnimplementedWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -651,7 +652,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA4() { ::grpc::Service::experimental().MarkMethodRawCallback(3, - new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA4(); })); } ~ExperimentalWithRawCallbackMethod_MethodA4() override { @@ -663,7 +664,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA4() { - return new ::grpc::internal::UnimplementedBidiReactor< + return new ::grpc_impl::internal::UnimplementedBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -814,7 +815,7 @@ class ServiceB final { public: ExperimentalWithCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, @@ -824,7 +825,7 @@ class ServiceB final { } void SetMessageAllocatorFor_MethodB1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } @@ -883,7 +884,7 @@ class ServiceB final { public: ExperimentalWithRawCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 501be844410..bdb36ae1a7b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -947,7 +947,9 @@ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ +include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ +include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -956,6 +958,7 @@ include/grpcpp/impl/codegen/call_op_set_interface.h \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ +include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -983,6 +986,7 @@ include/grpcpp/impl/codegen/rpc_service_method.h \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ +include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -995,6 +999,7 @@ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ +include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ include/grpcpp/impl/method_handler_impl.h \ @@ -1024,11 +1029,14 @@ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ +include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ +include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -1036,6 +1044,7 @@ include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -1043,6 +1052,7 @@ include/grpcpp/support/status_code_enum.h \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ +include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index f1dd2e54e1d..1abe2523b3c 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -948,7 +948,9 @@ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ +include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ +include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -957,6 +959,7 @@ include/grpcpp/impl/codegen/call_op_set_interface.h \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ +include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -985,6 +988,7 @@ include/grpcpp/impl/codegen/rpc_service_method.h \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ +include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -997,6 +1001,7 @@ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ +include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ include/grpcpp/impl/method_handler_impl.h \ @@ -1026,11 +1031,14 @@ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ +include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ +include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -1038,6 +1046,7 @@ include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -1045,6 +1054,7 @@ include/grpcpp/support/status_code_enum.h \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ +include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ src/core/ext/filters/client_channel/health/health.pb.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index d263e4fed22..51cb18b0932 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10170,7 +10170,9 @@ "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -10179,6 +10181,7 @@ "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -10201,6 +10204,7 @@ "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -10212,6 +10216,7 @@ "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h" ], "is_filegroup": true, @@ -10250,7 +10255,9 @@ "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -10259,6 +10266,7 @@ "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -10281,6 +10289,7 @@ "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -10292,6 +10301,7 @@ "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h" ], "third_party": false, @@ -10441,11 +10451,14 @@ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -10453,6 +10466,7 @@ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -10460,6 +10474,7 @@ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/cpp/client/create_channel_internal.h", @@ -10569,11 +10584,14 @@ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -10581,6 +10599,7 @@ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -10588,6 +10607,7 @@ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/cpp/client/channel_cc.cc", From 420d5413c7d9816df16cf24018c1f8b8dc2e8d09 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 10:50:47 -0700 Subject: [PATCH 524/676] Use the actual formula --- src/core/lib/iomgr/tcp_posix.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 0a2ef767598..606e033a21e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -435,9 +435,9 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; - char cmsgbuf - [128 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int))*/ - ]; + constexpr size_t cmsg_alloc_space = + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); + char cmsgbuf[cmsg_alloc_space]; ssize_t read_bytes; size_t total_read_bytes = 0; From f44e0c07a709c81211fb32d5010906a8451f63ca Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 10:55:11 -0700 Subject: [PATCH 525/676] Reviewer comments --- src/core/lib/iomgr/tcp_posix.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 606e033a21e..031f681baa3 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -526,6 +526,7 @@ static void tcp_do_read(grpc_tcp* tcp) { if (cmsg->cmsg_level == SOL_TCP && cmsg->cmsg_type == TCP_CM_INQ && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { tcp->inq = *reinterpret_cast(CMSG_DATA(cmsg)); + break; } } } From 7cb861ce294edae5d40e8ea0c597687e989eec17 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 11:00:55 -0700 Subject: [PATCH 526/676] Reviewer comments --- src/core/lib/iomgr/tcp_posix.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 031f681baa3..79c56d5f3df 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -437,12 +437,12 @@ static void tcp_do_read(grpc_tcp* tcp) { struct iovec iov[MAX_READ_IOVEC]; constexpr size_t cmsg_alloc_space = CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); - char cmsgbuf[cmsg_alloc_space]; ssize_t read_bytes; size_t total_read_bytes = 0; - size_t iov_len = std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); + char cmsgbuf[cmsg_alloc_space]; + for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); From a94e00dccf732e19ec33e22ca184a99d44ace042 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 11:15:40 -0700 Subject: [PATCH 527/676] Reviewer comments --- src/core/lib/iomgr/tcp_posix.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 79c56d5f3df..94a9da2ee49 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -435,14 +435,13 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; - constexpr size_t cmsg_alloc_space = - CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); ssize_t read_bytes; size_t total_read_bytes = 0; size_t iov_len = std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); + constexpr size_t cmsg_alloc_space = + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); char cmsgbuf[cmsg_alloc_space]; - for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); From 02ff96bd31f33a0c193f0766d87bb57ba438b2ef Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 11:46:52 -0700 Subject: [PATCH 528/676] No need to allocate space for receive timestamp if errqueue is not present --- src/core/lib/iomgr/tcp_posix.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 94a9da2ee49..0e153679ad7 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -439,8 +439,12 @@ static void tcp_do_read(grpc_tcp* tcp) { size_t total_read_bytes = 0; size_t iov_len = std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); +#ifdef GRPC_LINUX_ERRQUEUE constexpr size_t cmsg_alloc_space = CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); +#else + constexpr size_t cmsg_alloc_space = CMSG_SPACE(sizeof(int)); +#endif /* GRPC_LINUX_ERRQUEUE */ char cmsgbuf[cmsg_alloc_space]; for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); From 416d9434a864f751ad9db67cbec6236a3bbc7b5a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 13:38:11 -0700 Subject: [PATCH 529/676] Modify BUILD for threadpool --- BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILD b/BUILD index b2867e150b5..5faf39e7cde 100644 --- a/BUILD +++ b/BUILD @@ -785,6 +785,7 @@ grpc_cc_library( "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", "src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/core/lib/iomgr/executor/threadpool.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -943,6 +944,7 @@ grpc_cc_library( "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", From 410451c126e970513a90827503775b3417a7939a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 14:02:58 -0700 Subject: [PATCH 530/676] Add threadpool implementation --- BUILD.gn | 3 + CMakeLists.txt | 41 ++++ Makefile | 42 +++++ build.yaml | 12 ++ config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + src/core/lib/iomgr/executor/mpmcqueue.cc | 18 ++ src/core/lib/iomgr/executor/mpmcqueue.h | 5 + src/core/lib/iomgr/executor/threadpool.cc | 136 +++++++++++++ src/core/lib/iomgr/executor/threadpool.h | 153 +++++++++++++++ src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/iomgr/BUILD | 11 ++ test/core/iomgr/threadpool_test.cc | 178 ++++++++++++++++++ tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 19 ++ tools/run_tests/generated/tests.json | 24 +++ 22 files changed, 661 insertions(+) create mode 100644 src/core/lib/iomgr/executor/threadpool.cc create mode 100644 src/core/lib/iomgr/executor/threadpool.h create mode 100644 test/core/iomgr/threadpool_test.cc diff --git a/BUILD.gn b/BUILD.gn index 6b6a0f5c392..9d9d53f7ba5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -527,6 +527,8 @@ config("grpc_config") { "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/executor/mpmcqueue.cc", "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.cc", + "src/core/lib/iomgr/executor/threadpool.h", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname.h", @@ -1232,6 +1234,7 @@ config("grpc_config") { "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a914be54b3..93d9fe3a163 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,6 +428,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c tcp_server_posix_test) endif() add_dependencies(buildtests_c tcp_server_uv_test) +add_dependencies(buildtests_c threadpool_test) add_dependencies(buildtests_c time_averaged_stats_test) add_dependencies(buildtests_c timeout_encoding_test) add_dependencies(buildtests_c timer_heap_test) @@ -1032,6 +1033,7 @@ add_library(grpc src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1471,6 +1473,7 @@ add_library(grpc_cronet src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -1892,6 +1895,7 @@ add_library(grpc_test_util src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2226,6 +2230,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -2536,6 +2541,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -3567,6 +3573,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/exec_ctx.cc src/core/lib/iomgr/executor.cc src/core/lib/iomgr/executor/mpmcqueue.cc + src/core/lib/iomgr/executor/threadpool.cc src/core/lib/iomgr/fork_posix.cc src/core/lib/iomgr/fork_windows.cc src/core/lib/iomgr/gethostname_fallback.cc @@ -10508,6 +10515,40 @@ target_link_libraries(tcp_server_uv_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(threadpool_test + test/core/iomgr/threadpool_test.cc +) + + +target_include_directories(threadpool_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(threadpool_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(threadpool_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(threadpool_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(time_averaged_stats_test test/core/iomgr/time_averaged_stats_test.cc ) diff --git a/Makefile b/Makefile index fb43e7bb0b3..32b695c24ec 100644 --- a/Makefile +++ b/Makefile @@ -1133,6 +1133,7 @@ tcp_client_uv_test: $(BINDIR)/$(CONFIG)/tcp_client_uv_test tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test tcp_server_posix_test: $(BINDIR)/$(CONFIG)/tcp_server_posix_test tcp_server_uv_test: $(BINDIR)/$(CONFIG)/tcp_server_uv_test +threadpool_test: $(BINDIR)/$(CONFIG)/threadpool_test time_averaged_stats_test: $(BINDIR)/$(CONFIG)/time_averaged_stats_test timeout_encoding_test: $(BINDIR)/$(CONFIG)/timeout_encoding_test timer_heap_test: $(BINDIR)/$(CONFIG)/timer_heap_test @@ -1553,6 +1554,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/tcp_posix_test \ $(BINDIR)/$(CONFIG)/tcp_server_posix_test \ $(BINDIR)/$(CONFIG)/tcp_server_uv_test \ + $(BINDIR)/$(CONFIG)/threadpool_test \ $(BINDIR)/$(CONFIG)/time_averaged_stats_test \ $(BINDIR)/$(CONFIG)/timeout_encoding_test \ $(BINDIR)/$(CONFIG)/timer_heap_test \ @@ -2185,6 +2187,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/tcp_server_posix_test || ( echo test tcp_server_posix_test failed ; exit 1 ) $(E) "[RUN] Testing tcp_server_uv_test" $(Q) $(BINDIR)/$(CONFIG)/tcp_server_uv_test || ( echo test tcp_server_uv_test failed ; exit 1 ) + $(E) "[RUN] Testing threadpool_test" + $(Q) $(BINDIR)/$(CONFIG)/threadpool_test || ( echo test threadpool_test failed ; exit 1 ) $(E) "[RUN] Testing time_averaged_stats_test" $(Q) $(BINDIR)/$(CONFIG)/time_averaged_stats_test || ( echo test time_averaged_stats_test failed ; exit 1 ) $(E) "[RUN] Testing timeout_encoding_test" @@ -3540,6 +3544,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -3970,6 +3975,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4381,6 +4387,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4699,6 +4706,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -4980,6 +4988,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -5981,6 +5990,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ @@ -13426,6 +13436,38 @@ endif endif +THREADPOOL_TEST_SRC = \ + test/core/iomgr/threadpool_test.cc \ + +THREADPOOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(THREADPOOL_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/threadpool_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/threadpool_test: $(THREADPOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(THREADPOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/threadpool_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/threadpool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_threadpool_test: $(THREADPOOL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(THREADPOOL_TEST_OBJS:.o=.dep) +endif +endif + + TIME_AVERAGED_STATS_TEST_SRC = \ test/core/iomgr/time_averaged_stats_test.cc \ diff --git a/build.yaml b/build.yaml index 1b32902c6e7..4faddbc648a 100644 --- a/build.yaml +++ b/build.yaml @@ -281,6 +281,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.cc - src/core/lib/iomgr/executor.cc - src/core/lib/iomgr/executor/mpmcqueue.cc + - src/core/lib/iomgr/executor/threadpool.cc - src/core/lib/iomgr/fork_posix.cc - src/core/lib/iomgr/fork_windows.cc - src/core/lib/iomgr/gethostname_fallback.cc @@ -469,6 +470,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/executor/mpmcqueue.h + - src/core/lib/iomgr/executor/threadpool.h - src/core/lib/iomgr/gethostname.h - src/core/lib/iomgr/grpc_if_nametoindex.h - src/core/lib/iomgr/internal_errqueue.h @@ -3733,6 +3735,16 @@ targets: - gpr exclude_iomgrs: - native +- name: threadpool_test + build: test + language: c + src: + - test/core/iomgr/threadpool_test.cc + deps: + - grpc_test_util + - grpc + - gpr + uses_polling: false - name: time_averaged_stats_test build: test language: c diff --git a/config.m4 b/config.m4 index 1791a3ca27b..50b789bb7bb 100644 --- a/config.m4 +++ b/config.m4 @@ -128,6 +128,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/exec_ctx.cc \ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor/mpmcqueue.cc \ + src/core/lib/iomgr/executor/threadpool.cc \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname_fallback.cc \ diff --git a/config.w32 b/config.w32 index ddb5a39bc6c..7048f83facf 100644 --- a/config.w32 +++ b/config.w32 @@ -103,6 +103,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\exec_ctx.cc " + "src\\core\\lib\\iomgr\\executor.cc " + "src\\core\\lib\\iomgr\\executor\\mpmcqueue.cc " + + "src\\core\\lib\\iomgr\\executor\\threadpool.cc " + "src\\core\\lib\\iomgr\\fork_posix.cc " + "src\\core\\lib\\iomgr\\fork_windows.cc " + "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 14492edd0e6..fc13e792240 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -469,6 +469,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/executor/mpmcqueue.h', + 'src/core/lib/iomgr/executor/threadpool.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -675,6 +676,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/executor/mpmcqueue.h', + 'src/core/lib/iomgr/executor/threadpool.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 340c7b4b66b..44f94171ed5 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -438,6 +438,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/executor/mpmcqueue.h', + 'src/core/lib/iomgr/executor/threadpool.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', @@ -592,6 +593,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -1094,6 +1096,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/executor/mpmcqueue.h', + 'src/core/lib/iomgr/executor/threadpool.h', 'src/core/lib/iomgr/gethostname.h', 'src/core/lib/iomgr/grpc_if_nametoindex.h', 'src/core/lib/iomgr/internal_errqueue.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0249e0a1fcd..1f4cf237ada 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -372,6 +372,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.h ) + s.files += %w( src/core/lib/iomgr/executor/threadpool.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) s.files += %w( src/core/lib/iomgr/grpc_if_nametoindex.h ) s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) @@ -526,6 +527,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.cc ) s.files += %w( src/core/lib/iomgr/executor.cc ) s.files += %w( src/core/lib/iomgr/executor/mpmcqueue.cc ) + s.files += %w( src/core/lib/iomgr/executor/threadpool.cc ) s.files += %w( src/core/lib/iomgr/fork_posix.cc ) s.files += %w( src/core/lib/iomgr/fork_windows.cc ) s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) diff --git a/grpc.gyp b/grpc.gyp index 0bd5be75f00..5eeab74d4c7 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -310,6 +310,7 @@ 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -687,6 +688,7 @@ 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -938,6 +940,7 @@ 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', @@ -1165,6 +1168,7 @@ 'src/core/lib/iomgr/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', diff --git a/package.xml b/package.xml index 4467a11aae4..584c6510a60 100644 --- a/package.xml +++ b/package.xml @@ -377,6 +377,7 @@ + @@ -531,6 +532,7 @@ + diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 97429ec30c7..b1d54bdcf88 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -111,4 +111,22 @@ void* InfLenFIFOQueue::Get() { return PopFront(); } +void* InfLenFIFOQueue::Get(gpr_timespec* wait_time) { + MutexLock l(&mu_); + + if (count_.Load(MemoryOrder::RELAXED) == 0) { + gpr_timespec start_time; + start_time = gpr_now(GPR_CLOCK_MONOTONIC); + + num_waiters_++; + do { + wait_nonempty_.Wait(&mu_); + } while (count_.Load(MemoryOrder::RELAXED) == 0); + num_waiters_--; + *wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), start_time); + } + GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); + return PopFront(); +} + } // namespace grpc_core diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 8ece95699c7..fdb3de00e73 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -67,6 +67,11 @@ class InfLenFIFOQueue : public MPMCQueueInterface { // This routine will cause the thread to block if queue is currently empty. void* Get(); + // Same as Get(), but will record how long waited when getting. + // This routine should be only called when debug trace is on and wants to + // collect stats data. + void* Get(gpr_timespec* wait_time); + // Returns number of elements in queue currently. // There might be concurrently add/remove on queue, so count might change // quickly. diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc new file mode 100644 index 00000000000..82b1724c23a --- /dev/null +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -0,0 +1,136 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/executor/threadpool.h" + +namespace grpc_core { + +void ThreadPoolWorker::Run() { + while (true) { + void* elem; + + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { + // Updates stats and print + gpr_timespec wait_time = gpr_time_0(GPR_TIMESPAN); + elem = static_cast(queue_)->Get(&wait_time); + stats_.sleep_cycles = gpr_time_add(stats_.sleep_cycles, wait_time); + gpr_log(GPR_INFO, + "ThreadPool Worker [%s %d] Stats: sleep_cycles %f", + thd_name_, index_, gpr_timespec_to_micros(stats_.sleep_cycles)); + } else { + elem = static_cast(queue_)->Get(); + } + if (elem == nullptr) { + break; + } + // Runs closure + grpc_experimental_completion_queue_functor* closure = + static_cast(elem); + closure->functor_run(closure->internal_next, closure->internal_success); + } +} + +void ThreadPool::SharedThreadPoolConstructor() { + // All worker threads in thread pool must be joinable. + thread_options_.set_joinable(true); + + queue_ = New(); + threads_ = static_cast( + gpr_zalloc(num_threads_ * sizeof(ThreadPoolWorker*))); + for (int i = 0; i < num_threads_; ++i) { + threads_[i] = + New(thd_name_, this, queue_, thread_options_, i); + threads_[i]->Start(); + } +} + +size_t ThreadPool::DefaultStackSize() { +#if defined(__ANDROID__) || defined(__APPLE__) + return 1952 * 1024; +#else + return 64 * 1024; +#endif +} + +bool ThreadPool::HasBeenShutDown() { + return shut_down_.Load(MemoryOrder::ACQUIRE); +} + +ThreadPool::ThreadPool(int num_threads) : num_threads_(num_threads) { + thd_name_ = "ThreadPoolWorker"; + thread_options_ = Thread::Options(); + thread_options_.set_stack_size(DefaultStackSize()); + SharedThreadPoolConstructor(); +} + +ThreadPool::ThreadPool(int num_threads, const char* thd_name) + : num_threads_(num_threads), thd_name_(thd_name) { + thread_options_ = Thread::Options(); + thread_options_.set_stack_size(DefaultStackSize()); + SharedThreadPoolConstructor(); +} + +ThreadPool::ThreadPool(int num_threads, const char* thd_name, + const Thread::Options& thread_options) + : num_threads_(num_threads), + thd_name_(thd_name), + thread_options_(thread_options) { + if (thread_options_.stack_size() == 0) { + thread_options_.set_stack_size(DefaultStackSize()); + } + SharedThreadPoolConstructor(); +} + +ThreadPool::~ThreadPool() { + shut_down_.Store(false, MemoryOrder::RELEASE); + + for (int i = 0; i < num_threads_; ++i) { + queue_->Put(nullptr); + } + + for (int i = 0; i < num_threads_; ++i) { + threads_[i]->Join(); + } + + for (int i = 0; i < num_threads_; ++i) { + Delete(threads_[i]); + } + gpr_free(threads_); + Delete(queue_); +} + +void ThreadPool::Add(grpc_experimental_completion_queue_functor* closure) { + if (HasBeenShutDown()) { + gpr_log(GPR_ERROR, "ThreadPool Has Already Been Shut Down."); + } else { + queue_->Put(static_cast(closure)); + } +} + +int ThreadPool::num_pending_closures() const { return queue_->count(); } + +int ThreadPool::pool_capacity() const { return num_threads_; } + +const Thread::Options& ThreadPool::thread_options() const { + return thread_options_; +} + +const char* ThreadPool::thread_name() const { return thd_name_; } +} // namespace grpc_core diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h new file mode 100644 index 00000000000..b14f1051feb --- /dev/null +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -0,0 +1,153 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H +#define GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H + +#include + +#include + +#include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/iomgr/executor/mpmcqueue.h" + +namespace grpc_core { + +// A base abstract base class for threadpool. +// Threadpool is an executor that maintains a pool of threads sitting around +// and waiting for closures. A threadpool also maintains a queue of pending +// closures, when closures appearing in the queue, the threads in pool will +// pull them out and execute them. +class ThreadPoolInterface { + public: + // Waits for all pending closures to complete, then shuts down thread pool. + virtual ~ThreadPoolInterface() {} + + // Schedules a given closure for execution later. + // Depending on specific subclass implementation, this routine might cause + // current thread to be blocked (in case of unable to schedule). + // Closure should contain a function pointer and arguments it will take, more + // details for closure struct at /grpc/include/grpc/impl/codegen/grpc_types.h + virtual void Add(grpc_experimental_completion_queue_functor* closure) + GRPC_ABSTRACT; + + // Returns the current number of pending closures + virtual int num_pending_closures() const GRPC_ABSTRACT; + + // Returns the capacity of pool (number of worker threads in pool) + virtual int pool_capacity() const GRPC_ABSTRACT; + + // Thread option accessor + virtual const Thread::Options& thread_options() const GRPC_ABSTRACT; + + // Returns the thread name for threads in this ThreadPool. + virtual const char* thread_name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS +}; + +// Worker thread for threadpool. Executes closures in the queue, until getting a +// NULL closure. +class ThreadPoolWorker { + public: + ThreadPoolWorker(const char* thd_name, ThreadPoolInterface* pool, + MPMCQueueInterface* queue, Thread::Options& options, + int index) + : queue_(queue), thd_name_(thd_name), index_(index) { + thd_ = Thread( + thd_name, [](void* th) { static_cast(th)->Run(); }, + this, nullptr, options); + } + + ~ThreadPoolWorker() {} + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + GRPC_ABSTRACT_BASE_CLASS + + private: + // struct for tracking stats of thread + struct Stats { + gpr_timespec sleep_cycles; + Stats() { sleep_cycles = gpr_time_0(GPR_TIMESPAN); } + }; + + void Run(); // Pulls closures from queue and executes them + + MPMCQueueInterface* queue_; // Queue in thread pool to pull closures from + Thread thd_; // Thread wrapped in + Stats stats_; // Stats to be collected in run time + const char* thd_name_; // Name of thread + int index_; // Index in thread pool +}; + +// A fixed size thread pool implementation of abstract thread pool interface. +// In this implementation, the number of threads in pool is fixed, but the +// capacity of closure queue is unlimited. +class ThreadPool : public ThreadPoolInterface { + public: + // Creates a thread pool with size of "num_threads", with default thread name + // "ThreadPoolWorker" and all thread options set to default. + ThreadPool(int num_threads); + + // Same as ThreadPool(int num_threads) constructor, except + // that it also sets "thd_name" as the name of all threads in the thread pool. + ThreadPool(int num_threads, const char* thd_name); + + // Same as ThreadPool(const char *thd_name, int num_threads) constructor, + // except that is also set thread_options for threads. + // Notes for stack size: + // If the stack size field of the passed in Thread::Options is set to default + // value 0, default ThreadPool stack size will be used. The current default + // stack size of this implementation is 1952K for mobile platform and 64K for + // all others. + ThreadPool(int num_threads, const char* thd_name, + const Thread::Options& thread_options); + + // Waits for all pending closures to complete, then shuts down thread pool. + ~ThreadPool() override; + + // Adds given closure into pending queue immediately. Since closure queue has + // infinite length, this routine will not block. + void Add(grpc_experimental_completion_queue_functor* closure) override; + + int num_pending_closures() const override; + int pool_capacity() const override; + const Thread::Options& thread_options() const override; + const char* thread_name() const override; + + private: + int num_threads_ = 0; + const char* thd_name_ = nullptr; + Thread::Options thread_options_; + ThreadPoolWorker** threads_ = nullptr; // Array of worker threads + MPMCQueueInterface* queue_ = nullptr; + + Atomic shut_down_{false}; // Destructor has been called if set to true + + void SharedThreadPoolConstructor(); + // For ThreadPool, default stack size for mobile platform is 1952K. for other + // platforms is 64K. + size_t DefaultStackSize(); + bool HasBeenShutDown(); +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_THREADPOOL_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 72e19f02081..6a8b208b914 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/exec_ctx.cc', 'src/core/lib/iomgr/executor.cc', 'src/core/lib/iomgr/executor/mpmcqueue.cc', + 'src/core/lib/iomgr/executor/threadpool.cc', 'src/core/lib/iomgr/fork_posix.cc', 'src/core/lib/iomgr/fork_windows.cc', 'src/core/lib/iomgr/gethostname_fallback.cc', diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index af67d5de25e..808a635b80a 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -281,6 +281,17 @@ grpc_cc_test( tags = ["no_windows"], ) +grpc_cc_test( + name = "threadpool_test", + srcs = ["threadpool_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "time_averaged_stats_test", srcs = ["time_averaged_stats_test.cc"], diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc new file mode 100644 index 00000000000..a56db5b647a --- /dev/null +++ b/test/core/iomgr/threadpool_test.cc @@ -0,0 +1,178 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/executor/threadpool.h" + +#include "test/core/util/test_config.h" + +#define SMALL_THREAD_POOL_SIZE 20 +#define LARGE_THREAD_POOL_SIZE 100 +#define THREAD_SMALL_ITERATION 100 +#define THREAD_LARGE_ITERATION 10000 + +grpc_core::Mutex mu; + +// Simple functor for testing. It will count how many times being called. +class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { + public: + friend class SimpleFunctorCheckForAdd; + SimpleFunctorForAdd() : count_(0) { + functor_run = &SimpleFunctorForAdd::Run; + internal_next = this; + internal_success = 0; + } + ~SimpleFunctorForAdd() {} + static void Run(struct grpc_experimental_completion_queue_functor* cb, + int ok) { + auto* callback = static_cast(cb); + grpc_core::MutexLock l(&mu); + callback->count_++; + } + + int count() { + grpc_core::MutexLock l(&mu); + return count_; + } + + private: + int count_; +}; + +// Checks the given SimpleFunctorForAdd's count with a given number. +class SimpleFunctorCheckForAdd + : public grpc_experimental_completion_queue_functor { + public: + SimpleFunctorCheckForAdd( + struct grpc_experimental_completion_queue_functor* cb, int ok) { + functor_run = &SimpleFunctorCheckForAdd::Run; + internal_next = cb; + internal_success = ok; + } + ~SimpleFunctorCheckForAdd() {} + static void Run(struct grpc_experimental_completion_queue_functor* cb, + int ok) { + auto* callback = static_cast(cb); + GPR_ASSERT(callback->count_ == ok); + } +}; + +static void test_add(void) { + gpr_log(GPR_INFO, "test_add"); + grpc_core::ThreadPool* pool = + grpc_core::New(SMALL_THREAD_POOL_SIZE, "test_add"); + + SimpleFunctorForAdd* functor = grpc_core::New(); + for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + pool->Add(functor); + } + grpc_core::Delete(pool); + GPR_ASSERT(functor->count() == THREAD_SMALL_ITERATION); + grpc_core::Delete(functor); + gpr_log(GPR_DEBUG, "Done."); +} + +// Thread that adds closures to pool +class WorkThread { + public: + WorkThread(grpc_core::ThreadPool* pool, SimpleFunctorForAdd* cb, int num_add) + : num_add_(num_add), cb_(cb), pool_(pool) { + thd_ = grpc_core::Thread( + "thread_pool_test_add_thd", + [](void* th) { static_cast(th)->Run(); }, this); + } + ~WorkThread() {} + + void Start() { thd_.Start(); } + void Join() { thd_.Join(); } + + private: + void Run() { + for (int i = 0; i < num_add_; ++i) { + pool_->Add(cb_); + } + } + + int num_add_; + SimpleFunctorForAdd* cb_; + grpc_core::ThreadPool* pool_; + grpc_core::Thread thd_; +}; + +static void test_multi_add(void) { + gpr_log(GPR_INFO, "test_multi_add"); + const int num_work_thds = 10; + grpc_core::ThreadPool* pool = grpc_core::New( + LARGE_THREAD_POOL_SIZE, "test_multi_add"); + SimpleFunctorForAdd* functor = grpc_core::New(); + WorkThread** work_thds = static_cast( + gpr_zalloc(sizeof(WorkThread*) * num_work_thds)); + gpr_log(GPR_DEBUG, "Fork threads for adding..."); + for (int i = 0; i < num_work_thds; ++i) { + work_thds[i] = + grpc_core::New(pool, functor, THREAD_LARGE_ITERATION); + work_thds[i]->Start(); + } + // Wait for all threads finish + gpr_log(GPR_DEBUG, "Waiting for all work threads finish..."); + for (int i = 0; i < num_work_thds; ++i) { + work_thds[i]->Join(); + grpc_core::Delete(work_thds[i]); + } + gpr_free(work_thds); + gpr_log(GPR_DEBUG, "Done."); + gpr_log(GPR_DEBUG, "Waiting for all closures finish..."); + // Destructor of thread pool will wait for all closures to finish + grpc_core::Delete(pool); + GPR_ASSERT(functor->count() == THREAD_LARGE_ITERATION * num_work_thds); + grpc_core::Delete(functor); + gpr_log(GPR_DEBUG, "Done."); +} + +static void test_one_thread_FIFO(void) { + gpr_log(GPR_INFO, "test_one_thread_FIFO"); + grpc_core::ThreadPool* pool = + grpc_core::New(1, "test_one_thread_FIFO"); + SimpleFunctorForAdd* functor = grpc_core::New(); + SimpleFunctorCheckForAdd** check_functors = + static_cast(gpr_zalloc( + sizeof(SimpleFunctorCheckForAdd*) * THREAD_SMALL_ITERATION)); + for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + pool->Add(functor); + check_functors[i] = + grpc_core::New(functor, i + 1); + pool->Add(check_functors[i]); + } + // Destructor of pool will wait until all closures finished. + grpc_core::Delete(pool); + grpc_core::Delete(functor); + for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + grpc_core::Delete(check_functors[i]); + } + gpr_free(check_functors); + gpr_log(GPR_DEBUG, "Done."); +} + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + grpc_init(); + test_add(); + test_multi_add(); + test_one_thread_FIFO(); + grpc_shutdown(); + return 0; +} diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 79cc89e13e8..8254c5b58b1 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1134,6 +1134,7 @@ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/executor/mpmcqueue.h \ +src/core/lib/iomgr/executor/threadpool.h \ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/grpc_if_nametoindex.h \ src/core/lib/iomgr/internal_errqueue.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 273c56e0242..b9e26a3cb0f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1236,6 +1236,8 @@ src/core/lib/iomgr/executor.cc \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/executor/mpmcqueue.cc \ src/core/lib/iomgr/executor/mpmcqueue.h \ +src/core/lib/iomgr/executor/threadpool.cc \ +src/core/lib/iomgr/executor/threadpool.h \ src/core/lib/iomgr/fork_posix.cc \ src/core/lib/iomgr/fork_windows.cc \ src/core/lib/iomgr/gethostname.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b8a79b387b6..b098db5f3a9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2267,6 +2267,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "threadpool_test", + "src": [ + "test/core/iomgr/threadpool_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8509,6 +8525,7 @@ "src/core/lib/iomgr/exec_ctx.cc", "src/core/lib/iomgr/executor.cc", "src/core/lib/iomgr/executor/mpmcqueue.cc", + "src/core/lib/iomgr/executor/threadpool.cc", "src/core/lib/iomgr/fork_posix.cc", "src/core/lib/iomgr/fork_windows.cc", "src/core/lib/iomgr/gethostname_fallback.cc", @@ -8698,6 +8715,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", @@ -8857,6 +8875,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/executor/mpmcqueue.h", + "src/core/lib/iomgr/executor/threadpool.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/grpc_if_nametoindex.h", "src/core/lib/iomgr/internal_errqueue.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 2ac529238d5..c8d7ff50e1a 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2793,6 +2793,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "threadpool_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From bf994e48d90679f8571ba69781d9d5a31037f34b Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Mon, 1 Jul 2019 10:38:23 -0700 Subject: [PATCH 531/676] Move grpc async, callback and sync implementation to grpc_impl namespace --- BUILD | 10 + BUILD.gn | 10 + CMakeLists.txt | 40 + Makefile | 40 + build.yaml | 10 + gRPC-C++.podspec | 10 + include/grpcpp/channel_impl.h | 13 +- include/grpcpp/generic/generic_stub_impl.h | 41 +- .../impl/codegen/async_generic_service.h | 28 +- include/grpcpp/impl/codegen/async_stream.h | 1102 +-------------- .../grpcpp/impl/codegen/async_stream_impl.h | 1134 ++++++++++++++++ .../grpcpp/impl/codegen/async_unary_call.h | 291 +--- .../impl/codegen/async_unary_call_impl.h | 315 +++++ include/grpcpp/impl/codegen/byte_buffer.h | 19 +- include/grpcpp/impl/codegen/call_op_set.h | 2 +- .../grpcpp/impl/codegen/channel_interface.h | 47 +- include/grpcpp/impl/codegen/client_callback.h | 1003 +------------- .../impl/codegen/client_callback_impl.h | 1067 +++++++++++++++ .../grpcpp/impl/codegen/client_context_impl.h | 52 +- .../grpcpp/impl/codegen/client_unary_call.h | 4 +- .../impl/codegen/completion_queue_impl.h | 17 +- include/grpcpp/impl/codegen/server_callback.h | 1133 +--------------- .../impl/codegen/server_callback_impl.h | 1186 +++++++++++++++++ .../grpcpp/impl/codegen/server_context_impl.h | 54 +- include/grpcpp/impl/codegen/service_type.h | 20 +- include/grpcpp/impl/codegen/sync_stream.h | 914 +------------ .../grpcpp/impl/codegen/sync_stream_impl.h | 944 +++++++++++++ include/grpcpp/support/async_stream_impl.h | 24 + .../grpcpp/support/async_unary_call_impl.h | 24 + include/grpcpp/support/client_callback_impl.h | 24 + include/grpcpp/support/server_callback_impl.h | 24 + include/grpcpp/support/sync_stream_impl.h | 24 + src/compiler/cpp_generator.cc | 121 +- src/cpp/client/generic_stub.cc | 30 +- src/cpp/server/async_generic_service.cc | 4 +- .../health/default_health_check_service.h | 1 + src/cpp/server/server_builder.cc | 15 +- src/cpp/server/server_context.cc | 11 +- test/cpp/codegen/compiler_test_golden | 37 +- tools/doxygen/Doxyfile.c++ | 10 + tools/doxygen/Doxyfile.c++.internal | 10 + .../generated/sources_and_headers.json | 20 + 42 files changed, 5258 insertions(+), 4627 deletions(-) create mode 100644 include/grpcpp/impl/codegen/async_stream_impl.h create mode 100644 include/grpcpp/impl/codegen/async_unary_call_impl.h create mode 100644 include/grpcpp/impl/codegen/client_callback_impl.h create mode 100644 include/grpcpp/impl/codegen/server_callback_impl.h create mode 100644 include/grpcpp/impl/codegen/sync_stream_impl.h create mode 100644 include/grpcpp/support/async_stream_impl.h create mode 100644 include/grpcpp/support/async_unary_call_impl.h create mode 100644 include/grpcpp/support/client_callback_impl.h create mode 100644 include/grpcpp/support/server_callback_impl.h create mode 100644 include/grpcpp/support/sync_stream_impl.h diff --git a/BUILD b/BUILD index f7c97beaaaf..851e5011006 100644 --- a/BUILD +++ b/BUILD @@ -268,11 +268,14 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -280,6 +283,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -287,6 +291,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", ] @@ -2157,7 +2162,9 @@ grpc_cc_library( "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -2166,6 +2173,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -2188,6 +2196,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -2199,6 +2208,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h", ], deps = [ diff --git a/BUILD.gn b/BUILD.gn index 08625e9bd12..940c9b25c72 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1046,7 +1046,9 @@ config("grpc_config") { "include/grpcpp/impl/client_unary_call.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -1055,6 +1057,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -1083,6 +1086,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -1095,6 +1099,7 @@ config("grpc_config") { "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h", "include/grpcpp/impl/grpc_library.h", "include/grpcpp/impl/method_handler_impl.h", @@ -1124,11 +1129,14 @@ config("grpc_config") { "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -1136,6 +1144,7 @@ config("grpc_config") { "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -1143,6 +1152,7 @@ config("grpc_config") { "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/core/ext/transport/inproc/inproc_transport.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 90737ecfe29..4653b8f6013 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3221,11 +3221,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -3233,6 +3236,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -3240,6 +3244,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -3325,7 +3330,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -3334,6 +3341,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -3356,6 +3364,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -3367,6 +3376,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h include/grpc++/impl/codegen/proto_utils.h @@ -3846,11 +3856,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -3858,6 +3871,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -3865,6 +3879,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -3950,7 +3965,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -3959,6 +3976,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -3981,6 +3999,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -3992,6 +4011,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h include/grpc/census.h @@ -4387,7 +4407,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4396,6 +4418,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4418,6 +4441,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4429,6 +4453,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpc/impl/codegen/byte_buffer.h include/grpc/impl/codegen/byte_buffer_reader.h @@ -4588,7 +4613,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4597,6 +4624,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4619,6 +4647,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4630,6 +4659,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpc/impl/codegen/byte_buffer.h include/grpc/impl/codegen/byte_buffer_reader.h @@ -4846,11 +4876,14 @@ foreach(_hdr include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h + include/grpcpp/support/async_stream_impl.h include/grpcpp/support/async_unary_call.h + include/grpcpp/support/async_unary_call_impl.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h + include/grpcpp/support/client_callback_impl.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h include/grpcpp/support/interceptor.h @@ -4858,6 +4891,7 @@ foreach(_hdr include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h include/grpcpp/support/server_callback.h + include/grpcpp/support/server_callback_impl.h include/grpcpp/support/server_interceptor.h include/grpcpp/support/slice.h include/grpcpp/support/status.h @@ -4865,6 +4899,7 @@ foreach(_hdr include/grpcpp/support/string_ref.h include/grpcpp/support/stub_options.h include/grpcpp/support/sync_stream.h + include/grpcpp/support/sync_stream_impl.h include/grpcpp/support/time.h include/grpcpp/support/validate_service_config.h include/grpc/support/alloc.h @@ -4950,7 +4985,9 @@ foreach(_hdr include/grpc++/impl/codegen/time.h include/grpcpp/impl/codegen/async_generic_service.h include/grpcpp/impl/codegen/async_stream.h + include/grpcpp/impl/codegen/async_stream_impl.h include/grpcpp/impl/codegen/async_unary_call.h + include/grpcpp/impl/codegen/async_unary_call_impl.h include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h @@ -4959,6 +4996,7 @@ foreach(_hdr include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h + include/grpcpp/impl/codegen/client_callback_impl.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_context_impl.h include/grpcpp/impl/codegen/client_interceptor.h @@ -4981,6 +5019,7 @@ foreach(_hdr include/grpcpp/impl/codegen/security/auth_context.h include/grpcpp/impl/codegen/serialization_traits.h include/grpcpp/impl/codegen/server_callback.h + include/grpcpp/impl/codegen/server_callback_impl.h include/grpcpp/impl/codegen/server_context.h include/grpcpp/impl/codegen/server_context_impl.h include/grpcpp/impl/codegen/server_interceptor.h @@ -4992,6 +5031,7 @@ foreach(_hdr include/grpcpp/impl/codegen/string_ref.h include/grpcpp/impl/codegen/stub_options.h include/grpcpp/impl/codegen/sync_stream.h + include/grpcpp/impl/codegen/sync_stream_impl.h include/grpcpp/impl/codegen/time.h include/grpcpp/impl/codegen/sync.h ) diff --git a/Makefile b/Makefile index d5b4f55d8d8..6369a52c49c 100644 --- a/Makefile +++ b/Makefile @@ -5588,11 +5588,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -5600,6 +5603,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -5607,6 +5611,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -5692,7 +5697,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -5701,6 +5708,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -5723,6 +5731,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -5734,6 +5743,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ include/grpc++/impl/codegen/proto_utils.h \ @@ -6218,11 +6228,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -6230,6 +6243,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -6237,6 +6251,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -6322,7 +6337,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6331,6 +6348,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6353,6 +6371,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6364,6 +6383,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ include/grpc/census.h \ @@ -6731,7 +6751,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6740,6 +6762,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6762,6 +6785,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6773,6 +6797,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -6903,7 +6928,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -6912,6 +6939,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -6934,6 +6962,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -6945,6 +6974,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -7167,11 +7197,14 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ + include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ + include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ + include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -7179,6 +7212,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ + include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -7186,6 +7220,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ + include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ include/grpc/support/alloc.h \ @@ -7271,7 +7306,9 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/time.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ + include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ + include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -7280,6 +7317,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ + include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -7302,6 +7340,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ + include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -7313,6 +7352,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync_stream.h \ + include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/codegen/sync.h \ diff --git a/build.yaml b/build.yaml index 74482dab439..8d7445152f5 100644 --- a/build.yaml +++ b/build.yaml @@ -1251,7 +1251,9 @@ filegroups: - include/grpc++/impl/codegen/time.h - include/grpcpp/impl/codegen/async_generic_service.h - include/grpcpp/impl/codegen/async_stream.h + - include/grpcpp/impl/codegen/async_stream_impl.h - include/grpcpp/impl/codegen/async_unary_call.h + - include/grpcpp/impl/codegen/async_unary_call_impl.h - include/grpcpp/impl/codegen/byte_buffer.h - include/grpcpp/impl/codegen/call.h - include/grpcpp/impl/codegen/call_hook.h @@ -1260,6 +1262,7 @@ filegroups: - include/grpcpp/impl/codegen/callback_common.h - include/grpcpp/impl/codegen/channel_interface.h - include/grpcpp/impl/codegen/client_callback.h + - include/grpcpp/impl/codegen/client_callback_impl.h - include/grpcpp/impl/codegen/client_context.h - include/grpcpp/impl/codegen/client_context_impl.h - include/grpcpp/impl/codegen/client_interceptor.h @@ -1282,6 +1285,7 @@ filegroups: - include/grpcpp/impl/codegen/security/auth_context.h - include/grpcpp/impl/codegen/serialization_traits.h - include/grpcpp/impl/codegen/server_callback.h + - include/grpcpp/impl/codegen/server_callback_impl.h - include/grpcpp/impl/codegen/server_context.h - include/grpcpp/impl/codegen/server_context_impl.h - include/grpcpp/impl/codegen/server_interceptor.h @@ -1293,6 +1297,7 @@ filegroups: - include/grpcpp/impl/codegen/string_ref.h - include/grpcpp/impl/codegen/stub_options.h - include/grpcpp/impl/codegen/sync_stream.h + - include/grpcpp/impl/codegen/sync_stream_impl.h - include/grpcpp/impl/codegen/time.h uses: - grpc_codegen @@ -1411,11 +1416,14 @@ filegroups: - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h - include/grpcpp/support/async_stream.h + - include/grpcpp/support/async_stream_impl.h - include/grpcpp/support/async_unary_call.h + - include/grpcpp/support/async_unary_call_impl.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h - include/grpcpp/support/channel_arguments_impl.h - include/grpcpp/support/client_callback.h + - include/grpcpp/support/client_callback_impl.h - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h - include/grpcpp/support/interceptor.h @@ -1423,6 +1431,7 @@ filegroups: - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h - include/grpcpp/support/server_callback.h + - include/grpcpp/support/server_callback_impl.h - include/grpcpp/support/server_interceptor.h - include/grpcpp/support/slice.h - include/grpcpp/support/status.h @@ -1430,6 +1439,7 @@ filegroups: - include/grpcpp/support/string_ref.h - include/grpcpp/support/stub_options.h - include/grpcpp/support/sync_stream.h + - include/grpcpp/support/sync_stream_impl.h - include/grpcpp/support/time.h - include/grpcpp/support/validate_service_config.h headers: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a09173dc8f0..6933fd2c05b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -129,11 +129,14 @@ Pod::Spec.new do |s| 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', 'include/grpcpp/support/async_stream.h', + 'include/grpcpp/support/async_stream_impl.h', 'include/grpcpp/support/async_unary_call.h', + 'include/grpcpp/support/async_unary_call_impl.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', 'include/grpcpp/support/channel_arguments_impl.h', 'include/grpcpp/support/client_callback.h', + 'include/grpcpp/support/client_callback_impl.h', 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', 'include/grpcpp/support/interceptor.h', @@ -141,6 +144,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', 'include/grpcpp/support/server_callback.h', + 'include/grpcpp/support/server_callback_impl.h', 'include/grpcpp/support/server_interceptor.h', 'include/grpcpp/support/slice.h', 'include/grpcpp/support/status.h', @@ -148,11 +152,14 @@ Pod::Spec.new do |s| 'include/grpcpp/support/string_ref.h', 'include/grpcpp/support/stub_options.h', 'include/grpcpp/support/sync_stream.h', + 'include/grpcpp/support/sync_stream_impl.h', 'include/grpcpp/support/time.h', 'include/grpcpp/support/validate_service_config.h', 'include/grpcpp/impl/codegen/async_generic_service.h', 'include/grpcpp/impl/codegen/async_stream.h', + 'include/grpcpp/impl/codegen/async_stream_impl.h', 'include/grpcpp/impl/codegen/async_unary_call.h', + 'include/grpcpp/impl/codegen/async_unary_call_impl.h', 'include/grpcpp/impl/codegen/byte_buffer.h', 'include/grpcpp/impl/codegen/call.h', 'include/grpcpp/impl/codegen/call_hook.h', @@ -161,6 +168,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/callback_common.h', 'include/grpcpp/impl/codegen/channel_interface.h', 'include/grpcpp/impl/codegen/client_callback.h', + 'include/grpcpp/impl/codegen/client_callback_impl.h', 'include/grpcpp/impl/codegen/client_context.h', 'include/grpcpp/impl/codegen/client_context_impl.h', 'include/grpcpp/impl/codegen/client_interceptor.h', @@ -183,6 +191,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/security/auth_context.h', 'include/grpcpp/impl/codegen/serialization_traits.h', 'include/grpcpp/impl/codegen/server_callback.h', + 'include/grpcpp/impl/codegen/server_callback_impl.h', 'include/grpcpp/impl/codegen/server_context.h', 'include/grpcpp/impl/codegen/server_context_impl.h', 'include/grpcpp/impl/codegen/server_interceptor.h', @@ -194,6 +203,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/string_ref.h', 'include/grpcpp/impl/codegen/stub_options.h', 'include/grpcpp/impl/codegen/sync_stream.h', + 'include/grpcpp/impl/codegen/sync_stream_impl.h', 'include/grpcpp/impl/codegen/time.h', 'include/grpcpp/impl/codegen/sync.h' end diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index a7eee2b8981..9ff3118645f 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -86,22 +86,23 @@ class Channel final : public ::grpc::ChannelInterface, ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, ::grpc_impl::ClientContext* context, - ::grpc::CompletionQueue* cq) override; + ::grpc_impl::CompletionQueue* cq) override; void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, ::grpc::internal::Call* call) override; void* RegisterMethod(const char* method) override; void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - ::grpc::CompletionQueue* cq, void* tag) override; + ::grpc_impl::CompletionQueue* cq, + void* tag) override; bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; - ::grpc::CompletionQueue* CallbackCQ() override; + ::grpc_impl::CompletionQueue* CallbackCQ() override; ::grpc::internal::Call CreateCallInternal( const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq, + ::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq, size_t interceptor_pos) override; const grpc::string host_; @@ -114,7 +115,7 @@ class Channel final : public ::grpc::ChannelInterface, // with this channel (if any). It is set on the first call to CallbackCQ(). // It is _not owned_ by the channel; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). - ::grpc::CompletionQueue* callback_cq_ = nullptr; + ::grpc_impl::CompletionQueue* callback_cq_ = nullptr; std::vector< std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> diff --git a/include/grpcpp/generic/generic_stub_impl.h b/include/grpcpp/generic/generic_stub_impl.h index fdbc0d0a272..e670fcaa654 100644 --- a/include/grpcpp/generic/generic_stub_impl.h +++ b/include/grpcpp/generic/generic_stub_impl.h @@ -22,17 +22,20 @@ #include #include -#include -#include +#include +#include #include -#include +#include #include +#include + namespace grpc { -typedef ClientAsyncReaderWriter +typedef ::grpc_impl::ClientAsyncReaderWriter GenericClientAsyncReaderWriter; -typedef ClientAsyncResponseReader GenericClientAsyncResponseReader; +typedef ::grpc_impl::ClientAsyncResponseReader + GenericClientAsyncResponseReader; } // namespace grpc namespace grpc_impl { class CompletionQueue; @@ -50,15 +53,15 @@ class GenericStub final { /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr PrepareCall( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq); + CompletionQueue* cq); /// Setup a unary call to a named method \a method using \a context, and don't /// start it. Let it be started explicitly with StartCall. /// The return value only indicates whether or not registration of the call /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr PrepareUnaryCall( - grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer& request, grpc::CompletionQueue* cq); + grpc_impl::ClientContext* context, const grpc::string& method, + const grpc::ByteBuffer& request, CompletionQueue* cq); /// DEPRECATED for multi-threaded use /// Begin a call to a named method \a method using \a context. @@ -67,8 +70,8 @@ class GenericStub final { /// The return value only indicates whether or not registration of the call /// succeeded (i.e. the call won't proceed if the return value is nullptr). std::unique_ptr Call( - grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq, void* tag); + grpc_impl::ClientContext* context, const grpc::string& method, + CompletionQueue* cq, void* tag); /// NOTE: class experimental_type is not part of the public API of this class /// TODO(vjpai): Move these contents to the public API of GenericStub when @@ -79,23 +82,25 @@ class GenericStub final { /// Setup and start a unary call to a named method \a method using /// \a context and specifying the \a request and \a response buffers. - void UnaryCall(grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer* request, grpc::ByteBuffer* response, + void UnaryCall(grpc_impl::ClientContext* context, + const grpc::string& method, const grpc::ByteBuffer* request, + grpc::ByteBuffer* response, std::function on_completion); /// Setup and start a unary call to a named method \a method using /// \a context and specifying the \a request and \a response buffers. - void UnaryCall(grpc::ClientContext* context, const grpc::string& method, - const grpc::ByteBuffer* request, grpc::ByteBuffer* response, - grpc::experimental::ClientUnaryReactor* reactor); + void UnaryCall(grpc_impl::ClientContext* context, + const grpc::string& method, const grpc::ByteBuffer* request, + grpc::ByteBuffer* response, + grpc_impl::experimental::ClientUnaryReactor* reactor); /// Setup a call to a named method \a method using \a context and tied to /// \a reactor . Like any other bidi streaming RPC, it will not be activated /// until StartCall is invoked on its reactor. void PrepareBidiStreamingCall( - grpc::ClientContext* context, const grpc::string& method, - grpc::experimental::ClientBidiReactor* reactor); + grpc_impl::ClientContext* context, const grpc::string& method, + grpc_impl::experimental::ClientBidiReactor* reactor); private: GenericStub* stub_; diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index d8e6f49b2f3..7c720ce3c23 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -19,19 +19,21 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H #define GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H -#include +#include #include -#include +#include struct grpc_server; namespace grpc { -typedef ServerAsyncReaderWriter +typedef ::grpc_impl::ServerAsyncReaderWriter GenericServerAsyncReaderWriter; -typedef ServerAsyncResponseWriter GenericServerAsyncResponseWriter; -typedef ServerAsyncReader GenericServerAsyncReader; -typedef ServerAsyncWriter GenericServerAsyncWriter; +typedef ::grpc_impl::ServerAsyncResponseWriter + GenericServerAsyncResponseWriter; +typedef ::grpc_impl::ServerAsyncReader + GenericServerAsyncReader; +typedef ::grpc_impl::ServerAsyncWriter GenericServerAsyncWriter; class GenericServerContext final : public ::grpc_impl::ServerContext { public: @@ -75,8 +77,9 @@ class AsyncGenericService final { void RequestCall(GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag); + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag); private: friend class grpc_impl::Server; @@ -91,7 +94,8 @@ namespace experimental { /// GenericServerContext rather than a ServerContext. All other reaction and /// operation initiation APIs are the same as ServerBidiReactor. class ServerGenericBidiReactor - : public ServerBidiReactor { + : public ::grpc_impl::experimental::ServerBidiReactor { public: /// Similar to ServerBidiReactor::OnStarted except for argument type. /// @@ -137,8 +141,10 @@ class CallbackGenericService { private: friend class ::grpc_impl::Server; - internal::CallbackBidiHandler* Handler() { - return new internal::CallbackBidiHandler( + ::grpc_impl::internal::CallbackBidiHandler* + Handler() { + return new ::grpc_impl::internal::CallbackBidiHandler( [this] { return CreateReactor(); }); } diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index 417dceb587f..14dfe67962e 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -19,1117 +19,47 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H #define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -namespace internal { -/// Common interface for all client side asynchronous streaming. -class ClientAsyncStreamingInterface { - public: - virtual ~ClientAsyncStreamingInterface() {} - - /// Start the call that was set up by the constructor, but only if the - /// constructor was invoked through the "Prepare" API which doesn't actually - /// start the call - virtual void StartCall(void* tag) = 0; - - /// Request notification of the reading of the initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a AsyncReaderInterface::Read method. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Indicate that the stream is to be finished and request notification for - /// when the call has been ended. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when both: - /// * the client side has no more message to send - /// (this can be declared implicitly by calling this method, or - /// explicitly through an earlier call to the WritesDone method - /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or - /// \a ClientAsyncReaderWriterInterface::WritesDone). - /// * there are no more messages to be received from the server (this can - /// be known implicitly by the calling code, or explicitly from an - /// earlier call to \a AsyncReaderInterface::Read that yielded a failed - /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). - /// - /// The tag will be returned when either: - /// - all incoming messages have been read and the server has returned - /// a status. - /// - the server has returned a non-OK status. - /// - the call failed for some reason and the library generated a - /// status. - /// - /// Note that implementations of this method attempt to receive initial - /// metadata from the server if initial metadata hasn't yet been received. - /// - /// \param[in] tag Tag identifying this request. - /// \param[out] status To be updated with the operation status. - virtual void Finish(Status* status, void* tag) = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. -template -class AsyncReaderInterface { - public: - virtual ~AsyncReaderInterface() {} - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a AsyncReaderInterface::Read on the same stream since reads - /// on the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - /// - /// Side effect: note that this method attempt to receive initial metadata for - /// a stream if it hasn't yet been received. - virtual void Read(R* msg, void* tag) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class AsyncWriterInterface { - public: - virtual ~AsyncWriterInterface() {} - - /// Request the writing of \a msg with identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// This is thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, void* tag) = 0; - - /// Request the writing of \a msg using WriteOptions \a options with - /// identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// WriteOptions \a options is used to set the write options of this message. - /// This is thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, WriteOptions options, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with the writing - /// of trailing metadata, using WriteOptions \a options with - /// identifying tag \a tag. - /// - /// For client, WriteLast is equivalent of performing Write and - /// WritesDone in a single step. - /// For server, WriteLast buffers the \a msg. The writing of \a msg is held - /// until Finish is called, where \a msg and trailing metadata are coalesced - /// and write is initiated. Note that WriteLast can only buffer \a msg up to - /// the flow control window size. If \a msg size is larger than the window - /// size, it will be sent on wire without buffering. - /// - /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] tag The tag identifying the operation. - void WriteLast(const W& msg, WriteOptions options, void* tag) { - Write(msg, options.set_last_message(), tag); - } -}; - -} // namespace internal - template -class ClientAsyncReaderInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncReaderInterface {}; +using ClientAsyncReaderInterface = ::grpc_impl::ClientAsyncReaderInterface; -namespace internal { template -class ClientAsyncReaderFactory { - public: - /// Create a stream object. - /// Write the first request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started and - /// \a request has been written out. If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template - static ClientAsyncReader* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const W& request, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReader))) - ClientAsyncReader(call, context, request, start, tag); - } -}; -} // namespace internal - -/// Async client-side API for doing server-streaming RPCs, -/// where the incoming message stream coming from the server has -/// messages of type \a R. -template -class ClientAsyncReader final : public ClientAsyncReaderInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncReader)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata - /// method for semantics. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, - /// the \a ClientContext associated with this call is updated, and the - /// calling code can access the received metadata through the - /// \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - assert(started_); - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata received from the server. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } +using ClientAsyncReader = ::grpc_impl::ClientAsyncReader; - private: - friend class internal::ClientAsyncReaderFactory; - template - ClientAsyncReader(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, const W& request, - bool start, void* tag) - : context_(context), call_(call), started_(start) { - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); - init_ops_.ClientSendClose(); - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - init_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - init_ops_.set_output_tag(tag); - call_.PerformOps(&init_ops_); - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - init_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; - -/// Common interface for client side asynchronous writing. template -class ClientAsyncWriterInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncWriterInterface { - public: - /// Signal the client is done with the writes (half-close the client stream). - /// Thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; +using ClientAsyncWriterInterface = ::grpc_impl::ClientAsyncWriterInterface; -namespace internal { template -class ClientAsyncWriterFactory { - public: - /// Create a stream object. - /// Start the RPC if \a start is set - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, \a tag must be nullptr and the actual call - /// must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - /// \a response will be filled in with the single expected response - /// message from the server upon a successful call to the \a Finish - /// method of this instance. - template - static ClientAsyncWriter* Create(ChannelInterface* channel, - CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - R* response, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncWriter))) - ClientAsyncWriter(call, context, response, start, tag); - } -}; -} // namespace internal - -/// Async API on the client side for doing client-streaming RPCs, -/// where the outgoing message stream going to the server contains -/// messages of type \a W. -template -class ClientAsyncWriter final : public ClientAsyncWriterInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncWriter)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for - /// semantics. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, the \a ClientContext - /// associated with this call is updated, and the calling code can access - /// the received metadata through the \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } +using ClientAsyncWriter = ::grpc_impl::ClientAsyncWriter; - void WritesDone(void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - write_ops_.ClientSendClose(); - call_.PerformOps(&write_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata received from the server. - /// - attempts to fill in the \a response parameter passed to this class's - /// constructor with the server's response message. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class internal::ClientAsyncWriterFactory; - template - ClientAsyncWriter(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, R* response, - bool start, void* tag) - : context_(context), call_(call), started_(start) { - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - // if corked bit is set in context, we just keep the initial metadata - // buffered up to coalesce with later message send. No op is performed. - if (!context_->initial_metadata_corked_) { - write_ops_.set_output_tag(tag); - call_.PerformOps(&write_ops_); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpGenericRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; - -/// Async client-side interface for bi-directional streaming, -/// where the client-to-server message stream has messages of type \a W, -/// and the server-to-client message stream has messages of type \a R. template -class ClientAsyncReaderWriterInterface - : public internal::ClientAsyncStreamingInterface, - public internal::AsyncWriterInterface, - public internal::AsyncReaderInterface { - public: - /// Signal the client is done with the writes (half-close the client stream). - /// Thread-safe with respect to \a AsyncReaderInterface::Read - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; +using ClientAsyncReaderWriterInterface = + ::grpc_impl::ClientAsyncReaderWriterInterface; -namespace internal { template -class ClientAsyncReaderWriterFactory { - public: - /// Create a stream object. - /// Start the RPC request if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent). If \a start is not set, \a tag must be - /// nullptr and the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - static ClientAsyncReaderWriter* Create( - ChannelInterface* channel, CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, bool start, void* tag) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncReaderWriter))) - ClientAsyncReaderWriter(call, context, start, tag); - } -}; -} // namespace internal - -/// Async client-side interface for bi-directional streaming, -/// where the outgoing message stream going to the server -/// has messages of type \a W, and the incoming message stream coming -/// from the server has messages of type \a R. -template -class ClientAsyncReaderWriter final - : public ClientAsyncReaderWriterInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncReaderWriter)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall(void* tag) override { - assert(!started_); - started_ = true; - StartCallInternal(tag); - } - - /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method - /// for semantics of this method. - /// - /// Side effect: - /// - upon receiving initial metadata from the server, the \a ClientContext - /// is updated with it, and then the receiving initial metadata can - /// be accessed through this \a ClientContext. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - assert(started_); - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) override { - assert(started_); - write_ops_.set_output_tag(tag); - write_ops_.ClientSendClose(); - call_.PerformOps(&write_ops_); - } - - /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. - /// Side effect - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void Finish(Status* status, void* tag) override { - assert(started_); - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class internal::ClientAsyncReaderWriterFactory; - ClientAsyncReaderWriter(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, bool start, - void* tag) - : context_(context), call_(call), started_(start) { - if (start) { - StartCallInternal(tag); - } else { - assert(tag == nullptr); - } - } - - void StartCallInternal(void* tag) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - // if corked bit is set in context, we just keep the initial metadata - // buffered up to coalesce with later message send. No op is performed. - if (!context_->initial_metadata_corked_) { - write_ops_.set_output_tag(tag); - call_.PerformOps(&write_ops_); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::Call call_; - bool started_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; -}; +using ClientAsyncReaderWriter = ::grpc_impl::ClientAsyncReaderWriter; template -class ServerAsyncReaderInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncReaderInterface { - public: - /// Indicate that the stream is to be finished with a certain status code - /// and also send out \a msg response to the client. - /// Request notification for when the server has sent the response and the - /// appropriate signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous - /// \a AsyncReaderInterface::Read operation with a non-ok result, - /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if - /// some failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it - /// is safe to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - /// \param[in] msg To be sent to the client as the response for this call. - virtual void Finish(const W& msg, const Status& status, void* tag) = 0; - - /// Indicate that the stream is to be finished with a certain - /// non-OK status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// This call is meant to end the call with some error, and can be called at - /// any point that the server would like to "fail" the call (though note - /// this shouldn't be called concurrently with any other "sending" call, like - /// \a AsyncWriterInterface::Write). - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), and status, or if some failure occurred - /// when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once FinishWithError returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - /// - Note: \a status must have a non-OK code. - virtual void FinishWithError(const Status& status, void* tag) = 0; -}; +using ServerAsyncReaderInterface = + ::grpc_impl::ServerAsyncReaderInterface; -/// Async server-side API for doing client-streaming RPCs, -/// where the incoming message stream from the client has messages of type \a R, -/// and the single response message sent from the server is type \a W. template -class ServerAsyncReader final : public ServerAsyncReaderInterface { - public: - explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - /// See the \a ServerAsyncReaderInterface.Read method for semantics - /// - /// Side effect: - /// - also sends initial metadata if not alreay sent. - /// - uses the \a ServerContext associated with this call to send possible - /// initial and trailing metadata. - /// - /// Note: \a msg is not sent if \a status has a non-OK code. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once Finish returns. - void Finish(const W& msg, const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessage(msg)); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_ops_); - } - - /// See the \a ServerAsyncReaderInterface.Read method for semantics - /// - /// Side effect: - /// - also sends initial metadata if not alreay sent. - /// - uses the \a ServerContext associated with this call to send possible - /// initial and trailing metadata. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once FinishWithError returns. - void FinishWithError(const Status& status, void* tag) override { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; +using ServerAsyncReader = ::grpc_impl::ServerAsyncReader; template -class ServerAsyncWriterInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncWriterInterface { - public: - /// Indicate that the stream is to be finished with a certain status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when either: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous \a - /// AsyncReaderInterface::Read operation with a non-ok - /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'. - /// * it is desired to end the call early with some non-OK status code. - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if - /// some failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - virtual void Finish(const Status& status, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with trailing metadata which - /// contains \a status, using WriteOptions options with - /// identifying tag \a tag. - /// - /// WriteAndFinish is equivalent of performing WriteLast and Finish - /// in a single step. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] status The Status that server returns to client. - /// \param[in] tag The tag identifying the operation. - virtual void WriteAndFinish(const W& msg, WriteOptions options, - const Status& status, void* tag) = 0; -}; +using ServerAsyncWriterInterface = ::grpc_impl::ServerAsyncWriterInterface; -/// Async server-side API for doing server streaming RPCs, -/// where the outgoing message stream from the server has messages of type \a W. template -class ServerAsyncWriter final : public ServerAsyncWriterInterface { - public: - explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } +using ServerAsyncWriter = ::grpc_impl::ServerAsyncWriter; - void Write(const W& msg, WriteOptions options, void* tag) override { - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used - /// for sending trailing (and initial) metadata to the client. - /// - /// Note: \a status must have an OK code. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, - void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - options.set_buffer_hint(); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncWriterInterface.Finish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used for sending - /// trailing (and initial if not already sent) metadata to the client. - /// - /// Note: there are no restrictions are the code of - /// \a status,it may be non-OK - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - void Finish(const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&finish_ops_); - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - template - void EnsureInitialMetadataSent(T* ops) { - if (!ctx_->sent_initial_metadata_) { - ops->SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops->set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; - -/// Server-side interface for asynchronous bi-directional streaming. template -class ServerAsyncReaderWriterInterface - : public internal::ServerAsyncStreamingInterface, - public internal::AsyncWriterInterface, - public internal::AsyncReaderInterface { - public: - /// Indicate that the stream is to be finished with a certain status code. - /// Request notification for when the server has sent the appropriate - /// signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// It is appropriate to call this method when either: - /// * all messages from the client have been received (either known - /// implictly, or explicitly because a previous \a - /// AsyncReaderInterface::Read operation - /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' - /// with 'false'. - /// * it is desired to end the call early with some non-OK status code. - /// - /// This operation will end when the server has finished sending out initial - /// metadata (if not sent already), response message, and status, or if some - /// failure occurred when trying to do so. - /// - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of this call. - virtual void Finish(const Status& status, void* tag) = 0; - - /// Request the writing of \a msg and coalesce it with trailing metadata which - /// contains \a status, using WriteOptions options with - /// identifying tag \a tag. - /// - /// WriteAndFinish is equivalent of performing WriteLast and Finish in a - /// single step. - /// - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - /// - /// \param[in] msg The message to be written. - /// \param[in] options The WriteOptions to be used to write this message. - /// \param[in] status The Status that server returns to client. - /// \param[in] tag The tag identifying the operation. - virtual void WriteAndFinish(const W& msg, WriteOptions options, - const Status& status, void* tag) = 0; -}; +using ServerAsyncReaderWriterInterface = + ::grpc_impl::ServerAsyncReaderWriterInterface; -/// Async server-side API for doing bidirectional streaming RPCs, -/// where the incoming message stream coming from the client has messages of -/// type \a R, and the outgoing message stream coming from the server has -/// messages of type \a W. template -class ServerAsyncReaderWriter final - : public ServerAsyncReaderWriterInterface { - public: - explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Implicit input parameter: - /// - The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) override { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Write(const W& msg, WriteOptions options, void* tag) override { - write_ops_.set_output_tag(tag); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - EnsureInitialMetadataSent(&write_ops_); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish - /// method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used - /// for sending trailing (and initial) metadata to the client. - /// - /// Note: \a status must have an OK code. - // - /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it - /// is safe to deallocate once WriteAndFinish returns. - void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, - void* tag) override { - write_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&write_ops_); - options.set_buffer_hint(); - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); - write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&write_ops_); - } - - /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics. - /// - /// Implicit input parameter: - /// - the \a ServerContext associated with this call is used for sending - /// trailing (and initial if not already sent) metadata to the client. - /// - /// Note: there are no restrictions are the code of \a status, - /// it may be non-OK - // - /// gRPC doesn't take ownership or a reference to \a status, so it is safe to - /// to deallocate once Finish returns. - void Finish(const Status& status, void* tag) override { - finish_ops_.set_output_tag(tag); - EnsureInitialMetadataSent(&finish_ops_); - - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class ::grpc_impl::Server; - - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - template - void EnsureInitialMetadataSent(T* ops) { - if (!ctx_->sent_initial_metadata_) { - ops->SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops->set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - write_ops_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpServerSendStatus> - finish_ops_; -}; - +using ServerAsyncReaderWriter = ::grpc_impl::ServerAsyncReaderWriter; } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H diff --git a/include/grpcpp/impl/codegen/async_stream_impl.h b/include/grpcpp/impl/codegen/async_stream_impl.h new file mode 100644 index 00000000000..633a3d5dd00 --- /dev/null +++ b/include/grpcpp/impl/codegen/async_stream_impl.h @@ -0,0 +1,1134 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H +#define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H + +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +namespace internal { +/// Common interface for all client side asynchronous streaming. +class ClientAsyncStreamingInterface { + public: + virtual ~ClientAsyncStreamingInterface() {} + + /// Start the call that was set up by the constructor, but only if the + /// constructor was invoked through the "Prepare" API which doesn't actually + /// start the call + virtual void StartCall(void* tag) = 0; + + /// Request notification of the reading of the initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a AsyncReaderInterface::Read method. + /// + /// \param[in] tag Tag identifying this request. + virtual void ReadInitialMetadata(void* tag) = 0; + + /// Indicate that the stream is to be finished and request notification for + /// when the call has been ended. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when both: + /// * the client side has no more message to send + /// (this can be declared implicitly by calling this method, or + /// explicitly through an earlier call to the WritesDone method + /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or + /// \a ClientAsyncReaderWriterInterface::WritesDone). + /// * there are no more messages to be received from the server (this can + /// be known implicitly by the calling code, or explicitly from an + /// earlier call to \a AsyncReaderInterface::Read that yielded a failed + /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). + /// + /// The tag will be returned when either: + /// - all incoming messages have been read and the server has returned + /// a status. + /// - the server has returned a non-OK status. + /// - the call failed for some reason and the library generated a + /// status. + /// + /// Note that implementations of this method attempt to receive initial + /// metadata from the server if initial metadata hasn't yet been received. + /// + /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. + virtual void Finish(::grpc::Status* status, void* tag) = 0; +}; + +/// An interface that yields a sequence of messages of type \a R. +template +class AsyncReaderInterface { + public: + virtual ~AsyncReaderInterface() {} + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a AsyncReaderInterface::Read on the same stream since reads + /// on the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + /// + /// Side effect: note that this method attempt to receive initial metadata for + /// a stream if it hasn't yet been received. + virtual void Read(R* msg, void* tag) = 0; +}; + +/// An interface that can be fed a sequence of messages of type \a W. +template +class AsyncWriterInterface { + public: + virtual ~AsyncWriterInterface() {} + + /// Request the writing of \a msg with identifying tag \a tag. + /// + /// Only one write may be outstanding at any given time. This means that + /// after calling Write, one must wait to receive \a tag from the completion + /// queue BEFORE calling Write again. + /// This is thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] tag The tag identifying the operation. + virtual void Write(const W& msg, void* tag) = 0; + + /// Request the writing of \a msg using WriteOptions \a options with + /// identifying tag \a tag. + /// + /// Only one write may be outstanding at any given time. This means that + /// after calling Write, one must wait to receive \a tag from the completion + /// queue BEFORE calling Write again. + /// WriteOptions \a options is used to set the write options of this message. + /// This is thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] tag The tag identifying the operation. + virtual void Write(const W& msg, ::grpc::WriteOptions options, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with the writing + /// of trailing metadata, using WriteOptions \a options with + /// identifying tag \a tag. + /// + /// For client, WriteLast is equivalent of performing Write and + /// WritesDone in a single step. + /// For server, WriteLast buffers the \a msg. The writing of \a msg is held + /// until Finish is called, where \a msg and trailing metadata are coalesced + /// and write is initiated. Note that WriteLast can only buffer \a msg up to + /// the flow control window size. If \a msg size is larger than the window + /// size, it will be sent on wire without buffering. + /// + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] tag The tag identifying the operation. + void WriteLast(const W& msg, ::grpc::WriteOptions options, void* tag) { + Write(msg, options.set_last_message(), tag); + } +}; + +} // namespace internal + +template +class ClientAsyncReaderInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncReaderInterface {}; + +namespace internal { +template +class ClientAsyncReaderFactory { + public: + /// Create a stream object. + /// Write the first request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started and + /// \a request has been written out. If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template + static ClientAsyncReader* Create(::grpc::ChannelInterface* channel, + ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const W& request, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReader))) + ClientAsyncReader(call, context, request, start, tag); + } +}; +} // namespace internal + +/// Async client-side API for doing server-streaming RPCs, +/// where the incoming message stream coming from the server has +/// messages of type \a R. +template +class ClientAsyncReader final : public ClientAsyncReaderInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncReader)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata + /// method for semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, + /// the \a ClientContext associated with this call is updated, and the + /// calling code can access the received metadata through the + /// \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + assert(started_); + read_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + read_ops_.RecvInitialMetadata(context_); + } + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncReaderFactory; + template + ClientAsyncReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, const W& request, + bool start, void* tag) + : context_(context), call_(call), started_(start) { + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); + init_ops_.ClientSendClose(); + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + init_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + init_ops_.set_output_tag(tag); + call_.PerformOps(&init_ops_); + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + init_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +/// Common interface for client side asynchronous writing. +template +class ClientAsyncWriterInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncWriterInterface { + public: + /// Signal the client is done with the writes (half-close the client stream). + /// Thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// \param[in] tag The tag identifying the operation. + virtual void WritesDone(void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncWriterFactory { + public: + /// Create a stream object. + /// Start the RPC if \a start is set + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, \a tag must be nullptr and the actual call + /// must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + /// \a response will be filled in with the single expected response + /// message from the server upon a successful call to the \a Finish + /// method of this instance. + template + static ClientAsyncWriter* Create(::grpc::ChannelInterface* channel, + ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + R* response, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncWriter))) + ClientAsyncWriter(call, context, response, start, tag); + } +}; +} // namespace internal + +/// Async API on the client side for doing client-streaming RPCs, +/// where the outgoing message stream going to the server contains +/// messages of type \a W. +template +class ClientAsyncWriter final : public ClientAsyncWriterInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncWriter)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for + /// semantics. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, the \a ClientContext + /// associated with this call is updated, and the calling code can access + /// the received metadata through the \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Write(const W& msg, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WritesDone(void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + write_ops_.ClientSendClose(); + call_.PerformOps(&write_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata received from the server. + /// - attempts to fill in the \a response parameter passed to this class's + /// constructor with the server's response message. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncWriterFactory; + template + ClientAsyncWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, R* response, + bool start, void* tag) + : context_(context), call_(call), started_(start) { + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + // if corked bit is set in context, we just keep the initial metadata + // buffered up to coalesce with later message send. No op is performed. + if (!context_->initial_metadata_corked_) { + write_ops_.set_output_tag(tag); + call_.PerformOps(&write_ops_); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpGenericRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +/// Async client-side interface for bi-directional streaming, +/// where the client-to-server message stream has messages of type \a W, +/// and the server-to-client message stream has messages of type \a R. +template +class ClientAsyncReaderWriterInterface + : public internal::ClientAsyncStreamingInterface, + public internal::AsyncWriterInterface, + public internal::AsyncReaderInterface { + public: + /// Signal the client is done with the writes (half-close the client stream). + /// Thread-safe with respect to \a AsyncReaderInterface::Read + /// + /// \param[in] tag The tag identifying the operation. + virtual void WritesDone(void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncReaderWriterFactory { + public: + /// Create a stream object. + /// Start the RPC request if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent). If \a start is not set, \a tag must be + /// nullptr and the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + static ClientAsyncReaderWriter* Create( + ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, bool start, void* tag) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncReaderWriter))) + ClientAsyncReaderWriter(call, context, start, tag); + } +}; +} // namespace internal + +/// Async client-side interface for bi-directional streaming, +/// where the outgoing message stream going to the server +/// has messages of type \a W, and the incoming message stream coming +/// from the server has messages of type \a R. +template +class ClientAsyncReaderWriter final + : public ClientAsyncReaderWriterInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncReaderWriter)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall(void* tag) override { + assert(!started_); + started_ = true; + StartCallInternal(tag); + } + + /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method + /// for semantics of this method. + /// + /// Side effect: + /// - upon receiving initial metadata from the server, the \a ClientContext + /// is updated with it, and then the receiving initial metadata can + /// be accessed through this \a ClientContext. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + meta_ops_.set_output_tag(tag); + meta_ops_.RecvInitialMetadata(context_); + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + assert(started_); + read_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + read_ops_.RecvInitialMetadata(context_); + } + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + void Write(const W& msg, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WritesDone(void* tag) override { + assert(started_); + write_ops_.set_output_tag(tag); + write_ops_.ClientSendClose(); + call_.PerformOps(&write_ops_); + } + + /// See the \a ClientAsyncStreamingInterface.Finish method for semantics. + /// Side effect + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void Finish(::grpc::Status* status, void* tag) override { + assert(started_); + finish_ops_.set_output_tag(tag); + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class internal::ClientAsyncReaderWriterFactory; + ClientAsyncReaderWriter(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, bool start, + void* tag) + : context_(context), call_(call), started_(start) { + if (start) { + StartCallInternal(tag); + } else { + assert(tag == nullptr); + } + } + + void StartCallInternal(void* tag) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + // if corked bit is set in context, we just keep the initial metadata + // buffered up to coalesce with later message send. No op is performed. + if (!context_->initial_metadata_corked_) { + write_ops_.set_output_tag(tag); + call_.PerformOps(&write_ops_); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::Call call_; + bool started_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; +}; + +template +class ServerAsyncReaderInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncReaderInterface { + public: + /// Indicate that the stream is to be finished with a certain status code + /// and also send out \a msg response to the client. + /// Request notification for when the server has sent the response and the + /// appropriate signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous + /// \a AsyncReaderInterface::Read operation with a non-ok result, + /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if + /// some failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it + /// is safe to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// \param[in] msg To be sent to the client as the response for this call. + virtual void Finish(const W& msg, const ::grpc::Status& status, + void* tag) = 0; + + /// Indicate that the stream is to be finished with a certain + /// non-OK status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// This call is meant to end the call with some error, and can be called at + /// any point that the server would like to "fail" the call (though note + /// this shouldn't be called concurrently with any other "sending" call, like + /// \a AsyncWriterInterface::Write). + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), and status, or if some failure occurred + /// when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + /// - Note: \a status must have a non-OK code. + virtual void FinishWithError(const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing client-streaming RPCs, +/// where the incoming message stream from the client has messages of type \a R, +/// and the single response message sent from the server is type \a W. +template +class ServerAsyncReader final : public ServerAsyncReaderInterface { + public: + explicit ServerAsyncReader(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + read_ops_.set_output_tag(tag); + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. + /// + /// Note: \a msg is not sent if \a status has a non-OK code. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once Finish returns. + void Finish(const W& msg, const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (status.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessage(msg)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + } + call_.PerformOps(&finish_ops_); + } + + /// See the \a ServerAsyncReaderInterface.Read method for semantics + /// + /// Side effect: + /// - also sends initial metadata if not alreay sent. + /// - uses the \a ServerContext associated with this call to send possible + /// initial and trailing metadata. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. + void FinishWithError(const ::grpc::Status& status, void* tag) override { + GPR_CODEGEN_ASSERT(!status.ok()); + finish_ops_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +template +class ServerAsyncWriterInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncWriterInterface { + public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a + /// AsyncReaderInterface::Read operation with a non-ok + /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if + /// some failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + virtual void Finish(const ::grpc::Status& status, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with trailing metadata which + /// contains \a status, using WriteOptions options with + /// identifying tag \a tag. + /// + /// WriteAndFinish is equivalent of performing WriteLast and Finish + /// in a single step. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] status The Status that server returns to client. + /// \param[in] tag The tag identifying the operation. + virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing server streaming RPCs, +/// where the outgoing message stream from the server has messages of type \a W. +template +class ServerAsyncWriter final : public ServerAsyncWriterInterface { + public: + explicit ServerAsyncWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Write(const W& msg, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + options.set_buffer_hint(); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used for sending + /// trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of + /// \a status,it may be non-OK + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + void Finish(const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&finish_ops_); + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + template + void EnsureInitialMetadataSent(T* ops) { + if (!ctx_->sent_initial_metadata_) { + ops->SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops->set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +/// Server-side interface for asynchronous bi-directional streaming. +template +class ServerAsyncReaderWriterInterface + : public ::grpc::internal::ServerAsyncStreamingInterface, + public internal::AsyncWriterInterface, + public internal::AsyncReaderInterface { + public: + /// Indicate that the stream is to be finished with a certain status code. + /// Request notification for when the server has sent the appropriate + /// signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// It is appropriate to call this method when either: + /// * all messages from the client have been received (either known + /// implictly, or explicitly because a previous \a + /// AsyncReaderInterface::Read operation + /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' + /// with 'false'. + /// * it is desired to end the call early with some non-OK status code. + /// + /// This operation will end when the server has finished sending out initial + /// metadata (if not sent already), response message, and status, or if some + /// failure occurred when trying to do so. + /// + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of this call. + virtual void Finish(const ::grpc::Status& status, void* tag) = 0; + + /// Request the writing of \a msg and coalesce it with trailing metadata which + /// contains \a status, using WriteOptions options with + /// identifying tag \a tag. + /// + /// WriteAndFinish is equivalent of performing WriteLast and Finish in a + /// single step. + /// + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + /// + /// \param[in] msg The message to be written. + /// \param[in] options The WriteOptions to be used to write this message. + /// \param[in] status The Status that server returns to client. + /// \param[in] tag The tag identifying the operation. + virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) = 0; +}; + +/// Async server-side API for doing bidirectional streaming RPCs, +/// where the incoming message stream coming from the client has messages of +/// type \a R, and the outgoing message stream coming from the server has +/// messages of type \a W. +template +class ServerAsyncReaderWriter final + : public ServerAsyncReaderWriterInterface { + public: + explicit ServerAsyncReaderWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Implicit input parameter: + /// - The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_ops_.set_output_tag(tag); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_ops_); + } + + void Read(R* msg, void* tag) override { + read_ops_.set_output_tag(tag); + read_ops_.RecvMessage(msg); + call_.PerformOps(&read_ops_); + } + + void Write(const W& msg, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); + call_.PerformOps(&write_ops_); + } + + void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override { + write_ops_.set_output_tag(tag); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + EnsureInitialMetadataSent(&write_ops_); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish + /// method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used + /// for sending trailing (and initial) metadata to the client. + /// + /// Note: \a status must have an OK code. + // + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to deallocate once WriteAndFinish returns. + void WriteAndFinish(const W& msg, ::grpc::WriteOptions options, + const ::grpc::Status& status, void* tag) override { + write_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&write_ops_); + options.set_buffer_hint(); + GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok()); + write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&write_ops_); + } + + /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics. + /// + /// Implicit input parameter: + /// - the \a ServerContext associated with this call is used for sending + /// trailing (and initial if not already sent) metadata to the client. + /// + /// Note: there are no restrictions are the code of \a status, + /// it may be non-OK + // + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + void Finish(const ::grpc::Status& status, void* tag) override { + finish_ops_.set_output_tag(tag); + EnsureInitialMetadataSent(&finish_ops_); + + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_ops_); + } + + private: + friend class ::grpc_impl::Server; + + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + template + void EnsureInitialMetadataSent(T* ops) { + if (!ctx_->sent_initial_metadata_) { + ops->SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops->set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> read_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + write_ops_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpServerSendStatus> + finish_ops_; +}; + +} // namespace grpc_impl +#endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_IMPL_H diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 5da6a649f14..64ee17dec0d 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -19,299 +19,18 @@ #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H #define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -extern CoreCodegenInterface* g_core_codegen_interface; - -/// An interface relevant for async client side unary RPCs (which send -/// one request message to a server and receive one response message). -template -class ClientAsyncResponseReaderInterface { - public: - virtual ~ClientAsyncResponseReaderInterface() {} - - /// Start the call that was set up by the constructor, but only if the - /// constructor was invoked through the "Prepare" API which doesn't actually - /// start the call - virtual void StartCall() = 0; - - /// Request notification of the reading of initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Request to receive the server's response \a msg and final \a status for - /// the call, and to notify \a tag on this call's completion queue when - /// finished. - /// - /// This function will return when either: - /// - when the server's response message and status have been received. - /// - when the server has returned a non-OK status (no message expected in - /// this case). - /// - when the call failed for some reason and the library generated a - /// non-OK status. - /// - /// \param[in] tag Tag identifying this request. - /// \param[out] status To be updated with the operation status. - /// \param[out] msg To be filled in with the server's response message. - virtual void Finish(R* msg, Status* status, void* tag) = 0; -}; - -namespace internal { template -class ClientAsyncResponseReaderFactory { - public: - /// Start a call and write the request out if \a start is set. - /// \a tag will be notified on \a cq when the call has been started (i.e. - /// intitial metadata sent) and \a request has been written out. - /// If \a start is not set, the actual call must be initiated by StartCall - /// Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - template - static ClientAsyncResponseReader* Create( - ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const W& request, bool start) { - ::grpc::internal::Call call = channel->CreateCall(method, context, cq); - return new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientAsyncResponseReader))) - ClientAsyncResponseReader(call, context, request, start); - } -}; -} // namespace internal - -/// Async API for client-side unary RPCs, where the message response -/// received from the server is of type \a R. +using ClientAsyncResponseReaderInterface = + grpc_impl::ClientAsyncResponseReaderInterface; template -class ClientAsyncResponseReader final - : public ClientAsyncResponseReaderInterface { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientAsyncResponseReader)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall() override { - assert(!started_); - started_ = true; - StartCallInternal(); - } - - /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for - /// semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void ReadInitialMetadata(void* tag) override { - assert(started_); - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - single_buf.set_output_tag(tag); - single_buf.RecvInitialMetadata(context_); - call_.PerformOps(&single_buf); - initial_metadata_read_ = true; - } - - /// See \a ClientAysncResponseReaderInterface::Finish for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible initial and trailing metadata sent from the server. - void Finish(R* msg, Status* status, void* tag) override { - assert(started_); - if (initial_metadata_read_) { - finish_buf.set_output_tag(tag); - finish_buf.RecvMessage(msg); - finish_buf.AllowNoMessage(); - finish_buf.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_buf); - } else { - single_buf.set_output_tag(tag); - single_buf.RecvInitialMetadata(context_); - single_buf.RecvMessage(msg); - single_buf.AllowNoMessage(); - single_buf.ClientRecvStatus(context_, status); - call_.PerformOps(&single_buf); - } - } - - private: - friend class internal::ClientAsyncResponseReaderFactory; - ::grpc_impl::ClientContext* const context_; - ::grpc::internal::Call call_; - bool started_; - bool initial_metadata_read_ = false; +using ClientAsyncResponseReader = grpc_impl::ClientAsyncResponseReader; - template - ClientAsyncResponseReader(::grpc::internal::Call call, - ::grpc_impl::ClientContext* context, - const W& request, bool start) - : context_(context), call_(call), started_(start) { - // Bind the metadata at time of StartCallInternal but set up the rest here - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok()); - single_buf.ClientSendClose(); - if (start) StartCallInternal(); - } - - void StartCallInternal() { - single_buf.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - - // disable operator new - static void* operator new(std::size_t size); - static void* operator new(std::size_t size, void* p) { return p; } - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose, - ::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - single_buf; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_buf; -}; - -/// Async server-side API for handling unary calls, where the single -/// response message sent to the client is of type \a W. template -class ServerAsyncResponseWriter final - : public internal::ServerAsyncStreamingInterface { - public: - explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. - /// - /// Side effect: - /// The initial metadata that will be sent to the client from this op will - /// be taken from the \a ServerContext associated with the call. - /// - /// \param[in] tag Tag identifying this request. - void SendInitialMetadata(void* tag) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_buf_.set_output_tag(tag); - meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_buf_); - } - - /// Indicate that the stream is to be finished and request notification - /// when the server has sent the appropriate signals to the client to - /// end the call. Should not be used concurrently with other operations. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of the call. - /// \param[in] msg Message to be sent to the client. - /// - /// Side effect: - /// - also sends initial metadata if not already sent (using the - /// \a ServerContext associated with this call). - /// - /// Note: if \a status has a non-OK code, then \a msg will not be sent, - /// and the client will receive only the status with possible trailing - /// metadata. - void Finish(const W& msg, const Status& status, void* tag) { - finish_buf_.set_output_tag(tag); - finish_buf_.set_core_cq_tag(&finish_buf_); - if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_buf_.SendMessage(msg)); - } else { - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_buf_); - } - - /// Indicate that the stream is to be finished with a non-OK status, - /// and request notification for when the server has finished sending the - /// appropriate signals to the client to end the call. - /// Should not be used concurrently with other operations. - /// - /// \param[in] tag Tag identifying this request. - /// \param[in] status To be sent to the client as the result of the call. - /// - Note: \a status must have a non-OK code. - /// - /// Side effect: - /// - also sends initial metadata if not already sent (using the - /// \a ServerContext associated with this call). - void FinishWithError(const Status& status, void* tag) { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_buf_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_buf_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_buf_); - } - - private: - void BindCall(::grpc::internal::Call* call) override { call_ = *call; } - - ::grpc::internal::Call call_; - ::grpc_impl::ServerContext* ctx_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - meta_buf_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpServerSendStatus> - finish_buf_; -}; +using ServerAsyncResponseWriter = ::grpc_impl::ServerAsyncResponseWriter; } // namespace grpc -namespace std { -template -class default_delete> { - public: - void operator()(void* p) {} -}; -template -class default_delete> { - public: - void operator()(void* p) {} -}; -} // namespace std - #endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H diff --git a/include/grpcpp/impl/codegen/async_unary_call_impl.h b/include/grpcpp/impl/codegen/async_unary_call_impl.h new file mode 100644 index 00000000000..ff8bf15602b --- /dev/null +++ b/include/grpcpp/impl/codegen/async_unary_call_impl.h @@ -0,0 +1,315 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H +#define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H + +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +/// An interface relevant for async client side unary RPCs (which send +/// one request message to a server and receive one response message). +template +class ClientAsyncResponseReaderInterface { + public: + virtual ~ClientAsyncResponseReaderInterface() {} + + /// Start the call that was set up by the constructor, but only if the + /// constructor was invoked through the "Prepare" API which doesn't actually + /// start the call + virtual void StartCall() = 0; + + /// Request notification of the reading of initial metadata. Completion + /// will be notified by \a tag on the associated completion queue. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// \param[in] tag Tag identifying this request. + virtual void ReadInitialMetadata(void* tag) = 0; + + /// Request to receive the server's response \a msg and final \a status for + /// the call, and to notify \a tag on this call's completion queue when + /// finished. + /// + /// This function will return when either: + /// - when the server's response message and status have been received. + /// - when the server has returned a non-OK status (no message expected in + /// this case). + /// - when the call failed for some reason and the library generated a + /// non-OK status. + /// + /// \param[in] tag Tag identifying this request. + /// \param[out] status To be updated with the operation status. + /// \param[out] msg To be filled in with the server's response message. + virtual void Finish(R* msg, ::grpc::Status* status, void* tag) = 0; +}; + +namespace internal { +template +class ClientAsyncResponseReaderFactory { + public: + /// Start a call and write the request out if \a start is set. + /// \a tag will be notified on \a cq when the call has been started (i.e. + /// intitial metadata sent) and \a request has been written out. + /// If \a start is not set, the actual call must be initiated by StartCall + /// Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + template + static ClientAsyncResponseReader* Create( + ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request, bool start) { + ::grpc::internal::Call call = channel->CreateCall(method, context, cq); + return new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientAsyncResponseReader))) + ClientAsyncResponseReader(call, context, request, start); + } +}; +} // namespace internal + +/// Async API for client-side unary RPCs, where the message response +/// received from the server is of type \a R. +template +class ClientAsyncResponseReader final + : public ClientAsyncResponseReaderInterface { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientAsyncResponseReader)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + assert(!started_); + started_ = true; + StartCallInternal(); + } + + /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for + /// semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void ReadInitialMetadata(void* tag) override { + assert(started_); + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + single_buf.set_output_tag(tag); + single_buf.RecvInitialMetadata(context_); + call_.PerformOps(&single_buf); + initial_metadata_read_ = true; + } + + /// See \a ClientAysncResponseReaderInterface::Finish for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible initial and trailing metadata sent from the server. + void Finish(R* msg, ::grpc::Status* status, void* tag) override { + assert(started_); + if (initial_metadata_read_) { + finish_buf.set_output_tag(tag); + finish_buf.RecvMessage(msg); + finish_buf.AllowNoMessage(); + finish_buf.ClientRecvStatus(context_, status); + call_.PerformOps(&finish_buf); + } else { + single_buf.set_output_tag(tag); + single_buf.RecvInitialMetadata(context_); + single_buf.RecvMessage(msg); + single_buf.AllowNoMessage(); + single_buf.ClientRecvStatus(context_, status); + call_.PerformOps(&single_buf); + } + } + + private: + friend class internal::ClientAsyncResponseReaderFactory; + ::grpc_impl::ClientContext* const context_; + ::grpc::internal::Call call_; + bool started_; + bool initial_metadata_read_ = false; + + template + ClientAsyncResponseReader(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + const W& request, bool start) + : context_(context), call_(call), started_(start) { + // Bind the metadata at time of StartCallInternal but set up the rest here + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(single_buf.SendMessage(request).ok()); + single_buf.ClientSendClose(); + if (start) StartCallInternal(); + } + + void StartCallInternal() { + single_buf.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + + // disable operator new + static void* operator new(std::size_t size); + static void* operator new(std::size_t size, void* p) { return p; } + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose, + ::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + single_buf; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_buf; +}; + +/// Async server-side API for handling unary calls, where the single +/// response message sent to the client is of type \a W. +template +class ServerAsyncResponseWriter final + : public ::grpc::internal::ServerAsyncStreamingInterface { + public: + explicit ServerAsyncResponseWriter(::grpc_impl::ServerContext* ctx) + : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} + + /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics. + /// + /// Side effect: + /// The initial metadata that will be sent to the client from this op will + /// be taken from the \a ServerContext associated with the call. + /// + /// \param[in] tag Tag identifying this request. + void SendInitialMetadata(void* tag) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + meta_buf_.set_output_tag(tag); + meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_.PerformOps(&meta_buf_); + } + + /// Indicate that the stream is to be finished and request notification + /// when the server has sent the appropriate signals to the client to + /// end the call. Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// \param[in] msg Message to be sent to the client. + /// + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). + /// + /// Note: if \a status has a non-OK code, then \a msg will not be sent, + /// and the client will receive only the status with possible trailing + /// metadata. + void Finish(const W& msg, const ::grpc::Status& status, void* tag) { + finish_buf_.set_output_tag(tag); + finish_buf_.set_core_cq_tag(&finish_buf_); + if (!ctx_->sent_initial_metadata_) { + finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (status.ok()) { + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_buf_.SendMessage(msg)); + } else { + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); + } + call_.PerformOps(&finish_buf_); + } + + /// Indicate that the stream is to be finished with a non-OK status, + /// and request notification for when the server has finished sending the + /// appropriate signals to the client to end the call. + /// Should not be used concurrently with other operations. + /// + /// \param[in] tag Tag identifying this request. + /// \param[in] status To be sent to the client as the result of the call. + /// - Note: \a status must have a non-OK code. + /// + /// Side effect: + /// - also sends initial metadata if not already sent (using the + /// \a ServerContext associated with this call). + void FinishWithError(const ::grpc::Status& status, void* tag) { + GPR_CODEGEN_ASSERT(!status.ok()); + finish_buf_.set_output_tag(tag); + if (!ctx_->sent_initial_metadata_) { + finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, status); + call_.PerformOps(&finish_buf_); + } + + private: + void BindCall(::grpc::internal::Call* call) override { call_ = *call; } + + ::grpc::internal::Call call_; + ::grpc_impl::ServerContext* ctx_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + meta_buf_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpServerSendStatus> + finish_buf_; +}; + +} // namespace grpc_impl + +namespace std { +template +class default_delete<::grpc_impl::ClientAsyncResponseReader> { + public: + void operator()(void* p) {} +}; +template +class default_delete<::grpc_impl::ClientAsyncResponseReaderInterface> { + public: + void operator()(void* p) {} +}; +} // namespace std + +#endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_IMPL_H diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index e2ba9344bcb..0b7be6fc753 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -29,6 +29,17 @@ #include +namespace grpc_impl { +namespace internal { + +template +class CallbackUnaryHandler; +template +class CallbackServerStreamingHandler; + +} // namespace internal +} // namespace grpc_impl + namespace grpc { class ServerInterface; @@ -45,10 +56,6 @@ template class RpcMethodHandler; template class ServerStreamingHandler; -template -class CallbackUnaryHandler; -template -class CallbackServerStreamingHandler; template class ErrorMethodHandler; class ExternalConnectionAcceptorImpl; @@ -176,9 +183,9 @@ class ByteBuffer final { template friend class internal::ServerStreamingHandler; template - friend class internal::CallbackUnaryHandler; + friend class ::grpc_impl::internal::CallbackUnaryHandler; template - friend class ::grpc::internal::CallbackServerStreamingHandler; + friend class ::grpc_impl::internal::CallbackServerStreamingHandler; template friend class internal::ErrorMethodHandler; template diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index d0958bbb251..84d1407cbe2 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index 836c287e509..dd2fe8d687a 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -27,24 +27,13 @@ namespace grpc_impl { class ClientContext; class CompletionQueue; -} // namespace grpc_impl - -namespace grpc { -class ChannelInterface; - template class ClientReader; template class ClientWriter; template class ClientReaderWriter; - namespace internal { -class Call; -class CallOpSetInterface; -class RpcMethod; -template -class BlockingUnaryCallImpl; template class CallbackUnaryCallImpl; template @@ -62,7 +51,19 @@ class ClientCallbackReaderFactory; template class ClientCallbackWriterFactory; class ClientCallbackUnaryFactory; +} // namespace internal +} // namespace grpc_impl + +namespace grpc { +class ChannelInterface; + +namespace internal { +class Call; +class CallOpSetInterface; +class RpcMethod; class InterceptedChannel; +template +class BlockingUnaryCallImpl; } // namespace internal /// Codegen interface for \a grpc::Channel. @@ -102,30 +103,30 @@ class ChannelInterface { private: template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::internal::ClientAsyncReaderFactory; + friend class ::grpc_impl::internal::ClientAsyncReaderFactory; template - friend class ::grpc::internal::ClientAsyncWriterFactory; + friend class ::grpc_impl::internal::ClientAsyncWriterFactory; template - friend class ::grpc::internal::ClientAsyncReaderWriterFactory; + friend class ::grpc_impl::internal::ClientAsyncReaderWriterFactory; template - friend class ::grpc::internal::ClientAsyncResponseReaderFactory; + friend class ::grpc_impl::internal::ClientAsyncResponseReaderFactory; template - friend class ::grpc::internal::ClientCallbackReaderWriterFactory; + friend class ::grpc_impl::internal::ClientCallbackReaderWriterFactory; template - friend class ::grpc::internal::ClientCallbackReaderFactory; + friend class ::grpc_impl::internal::ClientCallbackReaderFactory; template - friend class ::grpc::internal::ClientCallbackWriterFactory; - friend class ::grpc::internal::ClientCallbackUnaryFactory; + friend class ::grpc_impl::internal::ClientCallbackWriterFactory; + friend class ::grpc_impl::internal::ClientCallbackUnaryFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; template - friend class ::grpc::internal::CallbackUnaryCallImpl; + friend class ::grpc_impl::internal::CallbackUnaryCallImpl; friend class ::grpc::internal::RpcMethod; friend class ::grpc::internal::InterceptedChannel; virtual internal::Call CreateCall(const internal::RpcMethod& method, diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 9441a48b051..4f60741624a 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -19,1012 +19,25 @@ #ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace grpc_impl { -class Channel; -class ClientContext; -} // namespace grpc_impl +#include namespace grpc { - -namespace internal { -class RpcMethod; - -/// Perform a callback-based unary call -/// TODO(vjpai): Combine as much as possible with the blocking unary call code -template -void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, - ::grpc_impl::ClientContext* context, - const InputMessage* request, OutputMessage* result, - std::function on_completion) { - CallbackUnaryCallImpl x( - channel, method, context, request, result, on_completion); -} - -template -class CallbackUnaryCallImpl { - public: - CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, - ::grpc_impl::ClientContext* context, - const InputMessage* request, OutputMessage* result, - std::function on_completion) { - CompletionQueue* cq = channel->CallbackCQ(); - GPR_CODEGEN_ASSERT(cq != nullptr); - Call call(channel->CreateCall(method, context, cq)); - - using FullCallOpSet = - CallOpSet, - CallOpClientSendClose, CallOpClientRecvStatus>; - - auto* ops = new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(FullCallOpSet))) FullCallOpSet; - - auto* tag = new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(CallbackWithStatusTag))) - CallbackWithStatusTag(call.call(), on_completion, ops); - - // TODO(vjpai): Unify code with sync API as much as possible - Status s = ops->SendMessagePtr(request); - if (!s.ok()) { - tag->force_run(s); - return; - } - ops->SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - ops->RecvInitialMetadata(context); - ops->RecvMessage(result); - ops->AllowNoMessage(); - ops->ClientSendClose(); - ops->ClientRecvStatus(context, tag->status_ptr()); - ops->set_core_cq_tag(tag); - call.PerformOps(ops); - } -}; -} // namespace internal - namespace experimental { -// Forward declarations -template -class ClientBidiReactor; template -class ClientReadReactor; -template -class ClientWriteReactor; -class ClientUnaryReactor; - -// NOTE: The streaming objects are not actually implemented in the public API. -// These interfaces are provided for mocking only. Typical applications -// will interact exclusively with the reactors that they define. -template -class ClientCallbackReaderWriter { - public: - virtual ~ClientCallbackReaderWriter() {} - virtual void StartCall() = 0; - virtual void Write(const Request* req, WriteOptions options) = 0; - virtual void WritesDone() = 0; - virtual void Read(Response* resp) = 0; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientBidiReactor* reactor) { - reactor->BindStream(this); - } -}; - -template -class ClientCallbackReader { - public: - virtual ~ClientCallbackReader() {} - virtual void StartCall() = 0; - virtual void Read(Response* resp) = 0; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientReadReactor* reactor) { - reactor->BindReader(this); - } -}; +using ClientReadReactor = + ::grpc_impl::experimental::ClientReadReactor; template -class ClientCallbackWriter { - public: - virtual ~ClientCallbackWriter() {} - virtual void StartCall() = 0; - void Write(const Request* req) { Write(req, WriteOptions()); } - virtual void Write(const Request* req, WriteOptions options) = 0; - void WriteLast(const Request* req, WriteOptions options) { - Write(req, options.set_last_message()); - } - virtual void WritesDone() = 0; +using ClientWriteReactor = + ::grpc_impl::experimental::ClientWriteReactor; - virtual void AddHold(int holds) = 0; - virtual void RemoveHold() = 0; - - protected: - void BindReactor(ClientWriteReactor* reactor) { - reactor->BindWriter(this); - } -}; - -class ClientCallbackUnary { - public: - virtual ~ClientCallbackUnary() {} - virtual void StartCall() = 0; - - protected: - void BindReactor(ClientUnaryReactor* reactor); -}; - -// The following classes are the reactor interfaces that are to be implemented -// by the user. They are passed in to the library as an argument to a call on a -// stub (either a codegen-ed call or a generic call). The streaming RPC is -// activated by calling StartCall, possibly after initiating StartRead, -// StartWrite, or AddHold operations on the streaming object. Note that none of -// the classes are pure; all reactions have a default empty reaction so that the -// user class only needs to override those classes that it cares about. -// The reactor must be passed to the stub invocation before any of the below -// operations can be called. - -/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. template -class ClientBidiReactor { - public: - virtual ~ClientBidiReactor() {} - - /// Activate the RPC and initiate any reads or writes that have been Start'ed - /// before this call. All streaming RPCs issued by the client MUST have - /// StartCall invoked on them (even if they are canceled) as this call is the - /// activation of their lifecycle. - void StartCall() { stream_->StartCall(); } - - /// Initiate a read operation (or post it for later initiation if StartCall - /// has not yet been invoked). - /// - /// \param[out] resp Where to eventually store the read message. Valid when - /// the library calls OnReadDone - void StartRead(Response* resp) { stream_->Read(resp); } - - /// Initiate a write operation (or post it for later initiation if StartCall - /// has not yet been invoked). - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } - - /// Initiate/post a write operation with specified options. - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - /// \param[in] options The WriteOptions to use for writing this message - void StartWrite(const Request* req, WriteOptions options) { - stream_->Write(req, std::move(options)); - } - - /// Initiate/post a write operation with specified options and an indication - /// that this is the last write (like StartWrite and StartWritesDone, merged). - /// Note that calling this means that no more calls to StartWrite, - /// StartWriteLast, or StartWritesDone are allowed. - /// - /// \param[in] req The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the application - /// regains ownership of msg. - /// \param[in] options The WriteOptions to use for writing this message - void StartWriteLast(const Request* req, WriteOptions options) { - StartWrite(req, std::move(options.set_last_message())); - } - - /// Indicate that the RPC will have no more write operations. This can only be - /// issued once for a given RPC. This is not required or allowed if - /// StartWriteLast is used since that already has the same implication. - /// Note that calling this means that no more calls to StartWrite, - /// StartWriteLast, or StartWritesDone are allowed. - void StartWritesDone() { stream_->WritesDone(); } - - /// Holds are needed if (and only if) this stream has operations that take - /// place on it after StartCall but from outside one of the reactions - /// (OnReadDone, etc). This is _not_ a common use of the streaming API. - /// - /// Holds must be added before calling StartCall. If a stream still has a hold - /// in place, its resources will not be destroyed even if the status has - /// already come in from the wire and there are currently no active callbacks - /// outstanding. Similarly, the stream will not call OnDone if there are still - /// holds on it. - /// - /// For example, if a StartRead or StartWrite operation is going to be - /// initiated from elsewhere in the application, the application should call - /// AddHold or AddMultipleHolds before StartCall. If there is going to be, - /// for example, a read-flow and a write-flow taking place outside the - /// reactions, then call AddMultipleHolds(2) before StartCall. When the - /// application knows that it won't issue any more read operations (such as - /// when a read comes back as not ok), it should issue a RemoveHold(). It - /// should also call RemoveHold() again after it does StartWriteLast or - /// StartWritesDone that indicates that there will be no more write ops. - /// The number of RemoveHold calls must match the total number of AddHold - /// calls plus the number of holds added by AddMultipleHolds. - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { stream_->AddHold(holds); } - void RemoveHold() { stream_->RemoveHold(); } - - /// Notifies the application that all operations associated with this RPC - /// have completed and provides the RPC status outcome. - /// - /// \param[in] s The status outcome of this RPC - virtual void OnDone(const Status& s) {} - - /// Notifies the application that a read of initial metadata from the - /// server is done. If the application chooses not to implement this method, - /// it can assume that the initial metadata has been read before the first - /// call of OnReadDone or OnDone. - /// - /// \param[in] ok Was the initial metadata read successfully? If false, no - /// further read-side operation will succeed. - virtual void OnReadInitialMetadataDone(bool ok) {} - - /// Notifies the application that a StartRead operation completed. - /// - /// \param[in] ok Was it successful? If false, no further read-side operation - /// will succeed. - virtual void OnReadDone(bool ok) {} - - /// Notifies the application that a StartWrite operation completed. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnWriteDone(bool ok) {} - - /// Notifies the application that a StartWritesDone operation completed. Note - /// that this is only used on explicit StartWritesDone operations and not for - /// those that are implicitly invoked as part of a StartWriteLast. - /// - /// \param[in] ok Was it successful? If false, the application will later see - /// the failure reflected as a bad status in OnDone. - virtual void OnWritesDoneDone(bool ok) {} - - private: - friend class ClientCallbackReaderWriter; - void BindStream(ClientCallbackReaderWriter* stream) { - stream_ = stream; - } - ClientCallbackReaderWriter* stream_; -}; - -/// \a ClientReadReactor is the interface for a server-streaming RPC. -/// All public methods behave as in ClientBidiReactor. -template -class ClientReadReactor { - public: - virtual ~ClientReadReactor() {} - - void StartCall() { reader_->StartCall(); } - void StartRead(Response* resp) { reader_->Read(resp); } - - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { reader_->AddHold(holds); } - void RemoveHold() { reader_->RemoveHold(); } - - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - - private: - friend class ClientCallbackReader; - void BindReader(ClientCallbackReader* reader) { reader_ = reader; } - ClientCallbackReader* reader_; -}; - -/// \a ClientWriteReactor is the interface for a client-streaming RPC. -/// All public methods behave as in ClientBidiReactor. -template -class ClientWriteReactor { - public: - virtual ~ClientWriteReactor() {} - - void StartCall() { writer_->StartCall(); } - void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } - void StartWrite(const Request* req, WriteOptions options) { - writer_->Write(req, std::move(options)); - } - void StartWriteLast(const Request* req, WriteOptions options) { - StartWrite(req, std::move(options.set_last_message())); - } - void StartWritesDone() { writer_->WritesDone(); } - - void AddHold() { AddMultipleHolds(1); } - void AddMultipleHolds(int holds) { writer_->AddHold(holds); } - void RemoveHold() { writer_->RemoveHold(); } - - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} - - private: - friend class ClientCallbackWriter; - void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } - ClientCallbackWriter* writer_; -}; - -/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. -/// This is _not_ a common way of invoking a unary RPC. In practice, this -/// option should be used only if the unary RPC wants to receive initial -/// metadata without waiting for the response to complete. Most deployments of -/// RPC systems do not use this option, but it is needed for generality. -/// All public methods behave as in ClientBidiReactor. -/// StartCall is included for consistency with the other reactor flavors: even -/// though there are no StartRead or StartWrite operations to queue before the -/// call (that is part of the unary call itself) and there is no reactor object -/// being created as a result of this call, we keep a consistent 2-phase -/// initiation API among all the reactor flavors. -class ClientUnaryReactor { - public: - virtual ~ClientUnaryReactor() {} - - void StartCall() { call_->StartCall(); } - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - - private: - friend class ClientCallbackUnary; - void BindCall(ClientCallbackUnary* call) { call_ = call; } - ClientCallbackUnary* call_; -}; - -// Define function out-of-line from class to avoid forward declaration issue -inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { - reactor->BindCall(this); -} +using ClientBidiReactor = + ::grpc_impl::experimental::ClientBidiReactor; +typedef ::grpc_impl::experimental::ClientUnaryReactor ClientUnaryReactor; } // namespace experimental - -namespace internal { - -// Forward declare factory classes for friendship -template -class ClientCallbackReaderWriterFactory; -template -class ClientCallbackReaderFactory; -template -class ClientCallbackWriterFactory; - -template -class ClientCallbackReaderWriterImpl - : public ::grpc::experimental::ClientCallbackReaderWriter { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackReaderWriterImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackReaderWriterImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any read backlog - // 3. Any write backlog - // 4. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - if (!start_corked_) { - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read and write tags so that they don't have to be set up - // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - if (read_ops_at_start_) { - call_.PerformOps(&read_ops_); - } - - if (write_ops_at_start_) { - call_.PerformOps(&write_ops_); - } - - if (writes_done_ops_at_start_) { - call_.PerformOps(&writes_done_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Read(Response* msg) override { - read_ops_.RecvMessage(msg); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&read_ops_); - } else { - read_ops_at_start_ = true; - } - } - - void Write(const Request* msg, WriteOptions options) override { - if (start_corked_) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&write_ops_); - } else { - write_ops_at_start_ = true; - } - } - void WritesDone() override { - if (start_corked_) { - writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); - writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&writes_done_ops_); - } else { - writes_done_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackReaderWriterFactory; - - ClientCallbackReaderWriterImpl( - Call call, ::grpc_impl::ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) - : context_(context), - call_(call), - reactor_(reactor), - start_corked_(context_->initial_metadata_corked_) { - this->BindReactor(reactor); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientBidiReactor* const reactor_; - - CallOpSet start_ops_; - CallbackWithSuccessTag start_tag_; - bool start_corked_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet - write_ops_; - CallbackWithSuccessTag write_tag_; - bool write_ops_at_start_{false}; - - CallOpSet writes_done_ops_; - CallbackWithSuccessTag writes_done_tag_; - bool writes_done_ops_at_start_{false}; - - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - bool read_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackReaderWriterFactory { - public: - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - ::grpc::experimental::ClientBidiReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackReaderWriterImpl))) - ClientCallbackReaderWriterImpl(call, context, - reactor); - } -}; - -template -class ClientCallbackReaderImpl - : public ::grpc::experimental::ClientCallbackReader { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackReaderImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackReaderImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any backlog - // 3. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read tag so it doesn't have to be set up each time - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeFinish(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - if (read_ops_at_start_) { - call_.PerformOps(&read_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Read(Response* msg) override { - read_ops_.RecvMessage(msg); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&read_ops_); - } else { - read_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackReaderFactory; - - template - ClientCallbackReaderImpl( - Call call, ::grpc_impl::ClientContext* context, Request* request, - ::grpc::experimental::ClientReadReactor* reactor) - : context_(context), call_(call), reactor_(reactor) { - this->BindReactor(reactor); - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); - start_ops_.ClientSendClose(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientReadReactor* const reactor_; - - CallOpSet - start_ops_; - CallbackWithSuccessTag start_tag_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - bool read_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackReaderFactory { - public: - template - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const Request* request, - ::grpc::experimental::ClientReadReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackReaderImpl))) - ClientCallbackReaderImpl(call, context, request, reactor); - } -}; - -template -class ClientCallbackWriterImpl - : public ::grpc::experimental::ClientCallbackWriter { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackWriterImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackWriterImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - void StartCall() override { - // This call initiates two batches, plus any backlog, each with a callback - // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Any backlog - // 3. Recv trailing metadata, on_completion callback - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - if (!start_corked_) { - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - } - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - // Also set up the read and write tags so that they don't have to be set up - // each time - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeFinish(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - - if (write_ops_at_start_) { - call_.PerformOps(&write_ops_); - } - - if (writes_done_ops_at_start_) { - call_.PerformOps(&writes_done_ops_); - } - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void Write(const Request* msg, WriteOptions options) override { - if (start_corked_) { - write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - - if (options.is_last_message()) { - options.set_buffer_hint(); - write_ops_.ClientSendClose(); - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&write_ops_); - } else { - write_ops_at_start_ = true; - } - } - void WritesDone() override { - if (start_corked_) { - writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_corked_ = false; - } - writes_done_ops_.ClientSendClose(); - writes_done_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWritesDoneDone(ok); - MaybeFinish(); - }, - &writes_done_ops_); - writes_done_ops_.set_core_cq_tag(&writes_done_tag_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (started_) { - call_.PerformOps(&writes_done_ops_); - } else { - writes_done_ops_at_start_ = true; - } - } - - void AddHold(int holds) override { - callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); - } - void RemoveHold() override { MaybeFinish(); } - - private: - friend class ClientCallbackWriterFactory; - - template - ClientCallbackWriterImpl( - Call call, ::grpc_impl::ClientContext* context, Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) - : context_(context), - call_(call), - reactor_(reactor), - start_corked_(context_->initial_metadata_corked_) { - this->BindReactor(reactor); - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientWriteReactor* const reactor_; - - CallOpSet start_ops_; - CallbackWithSuccessTag start_tag_; - bool start_corked_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - CallOpSet - write_ops_; - CallbackWithSuccessTag write_tag_; - bool write_ops_at_start_{false}; - - CallOpSet writes_done_ops_; - CallbackWithSuccessTag writes_done_tag_; - bool writes_done_ops_at_start_{false}; - - // Minimum of 2 callbacks to pre-register for start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -template -class ClientCallbackWriterFactory { - public: - template - static void Create( - ChannelInterface* channel, const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, Response* response, - ::grpc::experimental::ClientWriteReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackWriterImpl))) - ClientCallbackWriterImpl(call, context, response, reactor); - } -}; - -class ClientCallbackUnaryImpl final - : public ::grpc::experimental::ClientCallbackUnary { - public: - // always allocated against a call arena, no memory free required - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(ClientCallbackUnaryImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - void StartCall() override { - // This call initiates two batches, each with a callback - // 1. Send initial metadata + write + writes done + recv initial metadata - // 2. Read message, recv trailing metadata - started_ = true; - - start_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadInitialMetadataDone(ok); - MaybeFinish(); - }, - &start_ops_); - start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - start_ops_.RecvInitialMetadata(context_); - start_ops_.set_core_cq_tag(&start_tag_); - call_.PerformOps(&start_ops_); - - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void MaybeFinish() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - Status s = std::move(finish_status_); - auto* reactor = reactor_; - auto* call = call_.call(); - this->~ClientCallbackUnaryImpl(); - g_core_codegen_interface->grpc_call_unref(call); - reactor->OnDone(s); - } - } - - private: - friend class ClientCallbackUnaryFactory; - - template - ClientCallbackUnaryImpl(Call call, ::grpc_impl::ClientContext* context, - Request* request, Response* response, - ::grpc::experimental::ClientUnaryReactor* reactor) - : context_(context), call_(call), reactor_(reactor) { - this->BindReactor(reactor); - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); - start_ops_.ClientSendClose(); - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - } - - ::grpc_impl::ClientContext* const context_; - Call call_; - ::grpc::experimental::ClientUnaryReactor* const reactor_; - - CallOpSet - start_ops_; - CallbackWithSuccessTag start_tag_; - - CallOpSet finish_ops_; - CallbackWithSuccessTag finish_tag_; - Status finish_status_; - - // This call will have 2 callbacks: start and finish - std::atomic callbacks_outstanding_{2}; - bool started_{false}; -}; - -class ClientCallbackUnaryFactory { - public: - template - static void Create(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const Request* request, Response* response, - ::grpc::experimental::ClientUnaryReactor* reactor) { - Call call = channel->CreateCall(method, context, channel->CallbackCQ()); - - g_core_codegen_interface->grpc_call_ref(call.call()); - - new (g_core_codegen_interface->grpc_call_arena_alloc( - call.call(), sizeof(ClientCallbackUnaryImpl))) - ClientCallbackUnaryImpl(call, context, request, response, reactor); - } -}; - -} // namespace internal } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/client_callback_impl.h b/include/grpcpp/impl/codegen/client_callback_impl.h new file mode 100644 index 00000000000..81847bc9e04 --- /dev/null +++ b/include/grpcpp/impl/codegen/client_callback_impl.h @@ -0,0 +1,1067 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +namespace internal { +class RpcMethod; +} // namespace internal +} // namespace grpc + +namespace grpc_impl { +class Channel; +class ClientContext; + +namespace internal { + +/// Perform a callback-based unary call +/// TODO(vjpai): Combine as much as possible with the blocking unary call code +template +void CallbackUnaryCall(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, + std::function on_completion) { + CallbackUnaryCallImpl x( + channel, method, context, request, result, on_completion); +} + +template +class CallbackUnaryCallImpl { + public: + CallbackUnaryCallImpl(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const InputMessage* request, OutputMessage* result, + std::function on_completion) { + ::grpc_impl::CompletionQueue* cq = channel->CallbackCQ(); + GPR_CODEGEN_ASSERT(cq != nullptr); + grpc::internal::Call call(channel->CreateCall(method, context, cq)); + + using FullCallOpSet = grpc::internal::CallOpSet< + ::grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpSendMessage, + grpc::internal::CallOpRecvInitialMetadata, + grpc::internal::CallOpRecvMessage, + grpc::internal::CallOpClientSendClose, + grpc::internal::CallOpClientRecvStatus>; + + auto* ops = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(FullCallOpSet))) FullCallOpSet; + + auto* tag = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(grpc::internal::CallbackWithStatusTag))) + grpc::internal::CallbackWithStatusTag(call.call(), on_completion, ops); + + // TODO(vjpai): Unify code with sync API as much as possible + ::grpc::Status s = ops->SendMessagePtr(request); + if (!s.ok()) { + tag->force_run(s); + return; + } + ops->SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + ops->RecvInitialMetadata(context); + ops->RecvMessage(result); + ops->AllowNoMessage(); + ops->ClientSendClose(); + ops->ClientRecvStatus(context, tag->status_ptr()); + ops->set_core_cq_tag(tag); + call.PerformOps(ops); + } +}; +} // namespace internal + +namespace experimental { + +// Forward declarations +template +class ClientBidiReactor; +template +class ClientReadReactor; +template +class ClientWriteReactor; +class ClientUnaryReactor; + +// NOTE: The streaming objects are not actually implemented in the public API. +// These interfaces are provided for mocking only. Typical applications +// will interact exclusively with the reactors that they define. +template +class ClientCallbackReaderWriter { + public: + virtual ~ClientCallbackReaderWriter() {} + virtual void StartCall() = 0; + virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0; + virtual void WritesDone() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientBidiReactor* reactor) { + reactor->BindStream(this); + } +}; + +template +class ClientCallbackReader { + public: + virtual ~ClientCallbackReader() {} + virtual void StartCall() = 0; + virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientReadReactor* reactor) { + reactor->BindReader(this); + } +}; + +template +class ClientCallbackWriter { + public: + virtual ~ClientCallbackWriter() {} + virtual void StartCall() = 0; + void Write(const Request* req) { Write(req, ::grpc::WriteOptions()); } + virtual void Write(const Request* req, ::grpc::WriteOptions options) = 0; + void WriteLast(const Request* req, ::grpc::WriteOptions options) { + Write(req, options.set_last_message()); + } + virtual void WritesDone() = 0; + + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + + protected: + void BindReactor(ClientWriteReactor* reactor) { + reactor->BindWriter(this); + } +}; + +class ClientCallbackUnary { + public: + virtual ~ClientCallbackUnary() {} + virtual void StartCall() = 0; + + protected: + void BindReactor(ClientUnaryReactor* reactor); +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user. They are passed in to the library as an argument to a call on a +// stub (either a codegen-ed call or a generic call). The streaming RPC is +// activated by calling StartCall, possibly after initiating StartRead, +// StartWrite, or AddHold operations on the streaming object. Note that none of +// the classes are pure; all reactions have a default empty reaction so that the +// user class only needs to override those classes that it cares about. +// The reactor must be passed to the stub invocation before any of the below +// operations can be called. + +/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. +template +class ClientBidiReactor { + public: + virtual ~ClientBidiReactor() {} + + /// Activate the RPC and initiate any reads or writes that have been Start'ed + /// before this call. All streaming RPCs issued by the client MUST have + /// StartCall invoked on them (even if they are canceled) as this call is the + /// activation of their lifecycle. + void StartCall() { stream_->StartCall(); } + + /// Initiate a read operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[out] resp Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Response* resp) { stream_->Read(resp); } + + /// Initiate a write operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + void StartWrite(const Request* req) { + StartWrite(req, ::grpc::WriteOptions()); + } + + /// Initiate/post a write operation with specified options. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Request* req, ::grpc::WriteOptions options) { + stream_->Write(req, std::move(options)); + } + + /// Initiate/post a write operation with specified options and an indication + /// that this is the last write (like StartWrite and StartWritesDone, merged). + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Request* req, ::grpc::WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + + /// Indicate that the RPC will have no more write operations. This can only be + /// issued once for a given RPC. This is not required or allowed if + /// StartWriteLast is used since that already has the same implication. + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + void StartWritesDone() { stream_->WritesDone(); } + + /// Holds are needed if (and only if) this stream has operations that take + /// place on it after StartCall but from outside one of the reactions + /// (OnReadDone, etc). This is _not_ a common use of the streaming API. + /// + /// Holds must be added before calling StartCall. If a stream still has a hold + /// in place, its resources will not be destroyed even if the status has + /// already come in from the wire and there are currently no active callbacks + /// outstanding. Similarly, the stream will not call OnDone if there are still + /// holds on it. + /// + /// For example, if a StartRead or StartWrite operation is going to be + /// initiated from elsewhere in the application, the application should call + /// AddHold or AddMultipleHolds before StartCall. If there is going to be, + /// for example, a read-flow and a write-flow taking place outside the + /// reactions, then call AddMultipleHolds(2) before StartCall. When the + /// application knows that it won't issue any more read operations (such as + /// when a read comes back as not ok), it should issue a RemoveHold(). It + /// should also call RemoveHold() again after it does StartWriteLast or + /// StartWritesDone that indicates that there will be no more write ops. + /// The number of RemoveHold calls must match the total number of AddHold + /// calls plus the number of holds added by AddMultipleHolds. + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { stream_->AddHold(holds); } + void RemoveHold() { stream_->RemoveHold(); } + + /// Notifies the application that all operations associated with this RPC + /// have completed and provides the RPC status outcome. + /// + /// \param[in] s The status outcome of this RPC + virtual void OnDone(const ::grpc::Status& s) {} + + /// Notifies the application that a read of initial metadata from the + /// server is done. If the application chooses not to implement this method, + /// it can assume that the initial metadata has been read before the first + /// call of OnReadDone or OnDone. + /// + /// \param[in] ok Was the initial metadata read successfully? If false, no + /// further read-side operation will succeed. + virtual void OnReadInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite operation completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that a StartWritesDone operation completed. Note + /// that this is only used on explicit StartWritesDone operations and not for + /// those that are implicitly invoked as part of a StartWriteLast. + /// + /// \param[in] ok Was it successful? If false, the application will later see + /// the failure reflected as a bad status in OnDone. + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackReaderWriter; + void BindStream(ClientCallbackReaderWriter* stream) { + stream_ = stream; + } + ClientCallbackReaderWriter* stream_; +}; + +/// \a ClientReadReactor is the interface for a server-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientReadReactor { + public: + virtual ~ClientReadReactor() {} + + void StartCall() { reader_->StartCall(); } + void StartRead(Response* resp) { reader_->Read(resp); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { reader_->AddHold(holds); } + void RemoveHold() { reader_->RemoveHold(); } + + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + + private: + friend class ClientCallbackReader; + void BindReader(ClientCallbackReader* reader) { reader_ = reader; } + ClientCallbackReader* reader_; +}; + +/// \a ClientWriteReactor is the interface for a client-streaming RPC. +/// All public methods behave as in ClientBidiReactor. +template +class ClientWriteReactor { + public: + virtual ~ClientWriteReactor() {} + + void StartCall() { writer_->StartCall(); } + void StartWrite(const Request* req) { + StartWrite(req, ::grpc::WriteOptions()); + } + void StartWrite(const Request* req, ::grpc::WriteOptions options) { + writer_->Write(req, std::move(options)); + } + void StartWriteLast(const Request* req, ::grpc::WriteOptions options) { + StartWrite(req, std::move(options.set_last_message())); + } + void StartWritesDone() { writer_->WritesDone(); } + + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { writer_->AddHold(holds); } + void RemoveHold() { writer_->RemoveHold(); } + + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} + + private: + friend class ClientCallbackWriter; + void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } + ClientCallbackWriter* writer_; +}; + +/// \a ClientUnaryReactor is a reactor-style interface for a unary RPC. +/// This is _not_ a common way of invoking a unary RPC. In practice, this +/// option should be used only if the unary RPC wants to receive initial +/// metadata without waiting for the response to complete. Most deployments of +/// RPC systems do not use this option, but it is needed for generality. +/// All public methods behave as in ClientBidiReactor. +/// StartCall is included for consistency with the other reactor flavors: even +/// though there are no StartRead or StartWrite operations to queue before the +/// call (that is part of the unary call itself) and there is no reactor object +/// being created as a result of this call, we keep a consistent 2-phase +/// initiation API among all the reactor flavors. +class ClientUnaryReactor { + public: + virtual ~ClientUnaryReactor() {} + + void StartCall() { call_->StartCall(); } + virtual void OnDone(const ::grpc::Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + + private: + friend class ClientCallbackUnary; + void BindCall(ClientCallbackUnary* call) { call_ = call; } + ClientCallbackUnary* call_; +}; + +// Define function out-of-line from class to avoid forward declaration issue +inline void ClientCallbackUnary::BindReactor(ClientUnaryReactor* reactor) { + reactor->BindCall(this); +} + +} // namespace experimental + +namespace internal { + +// Forward declare factory classes for friendship +template +class ClientCallbackReaderWriterFactory; +template +class ClientCallbackReaderFactory; +template +class ClientCallbackWriterFactory; + +template +class ClientCallbackReaderWriterImpl + : public experimental::ClientCallbackReaderWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderWriterImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any read backlog + // 3. Any write backlog + // 4. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + void Write(const Request* msg, ::grpc::WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderWriterFactory; + + ClientCallbackReaderWriterImpl( + grpc::internal::Call call, ::grpc_impl::ClientContext* context, + experimental::ClientBidiReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientBidiReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + bool start_corked_; + + grpc::internal::CallOpSet finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + grpc::internal::CallOpSet + writes_done_ops_; + grpc::internal::CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderWriterFactory { + public: + static void Create( + ::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + experimental::ClientBidiReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderWriterImpl))) + ClientCallbackReaderWriterImpl(call, context, + reactor); + } +}; + +template +class ClientCallbackReaderImpl + : public experimental::ClientCallbackReader { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackReaderImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackReaderImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read tag so it doesn't have to be set up each time + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeFinish(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + if (read_ops_at_start_) { + call_.PerformOps(&read_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Read(Response* msg) override { + read_ops_.RecvMessage(msg); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&read_ops_); + } else { + read_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackReaderFactory; + + template + ClientCallbackReaderImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + Request* request, + experimental::ClientReadReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientReadReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + + grpc::internal::CallOpSet finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + bool read_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackReaderFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const Request* request, + experimental::ClientReadReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackReaderImpl))) + ClientCallbackReaderImpl(call, context, request, reactor); + } +}; + +template +class ClientCallbackWriterImpl + : public experimental::ClientCallbackWriter { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackWriterImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackWriterImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + void StartCall() override { + // This call initiates two batches, plus any backlog, each with a callback + // 1. Send initial metadata (unless corked) + recv initial metadata + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + if (!start_corked_) { + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + } + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + // Also set up the read and write tags so that they don't have to be set up + // each time + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeFinish(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + + if (write_ops_at_start_) { + call_.PerformOps(&write_ops_); + } + + if (writes_done_ops_at_start_) { + call_.PerformOps(&writes_done_ops_); + } + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void Write(const Request* msg, ::grpc::WriteOptions options) override { + if (start_corked_) { + write_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + + if (options.is_last_message()) { + options.set_buffer_hint(); + write_ops_.ClientSendClose(); + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(msg, options).ok()); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&write_ops_); + } else { + write_ops_at_start_ = true; + } + } + void WritesDone() override { + if (start_corked_) { + writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_corked_ = false; + } + writes_done_ops_.ClientSendClose(); + writes_done_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWritesDoneDone(ok); + MaybeFinish(); + }, + &writes_done_ops_); + writes_done_ops_.set_core_cq_tag(&writes_done_tag_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (started_) { + call_.PerformOps(&writes_done_ops_); + } else { + writes_done_ops_at_start_ = true; + } + } + + void AddHold(int holds) override { + callbacks_outstanding_.fetch_add(holds, std::memory_order_relaxed); + } + void RemoveHold() override { MaybeFinish(); } + + private: + friend class ClientCallbackWriterFactory; + + template + ClientCallbackWriterImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, + Response* response, + experimental::ClientWriteReactor* reactor) + : context_(context), + call_(call), + reactor_(reactor), + start_corked_(context_->initial_metadata_corked_) { + this->BindReactor(reactor); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientWriteReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + bool start_corked_; + + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + bool write_ops_at_start_{false}; + + grpc::internal::CallOpSet + writes_done_ops_; + grpc::internal::CallbackWithSuccessTag writes_done_tag_; + bool writes_done_ops_at_start_{false}; + + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +template +class ClientCallbackWriterFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, Response* response, + experimental::ClientWriteReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackWriterImpl))) + ClientCallbackWriterImpl(call, context, response, reactor); + } +}; + +class ClientCallbackUnaryImpl final : public experimental::ClientCallbackUnary { + public: + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(ClientCallbackUnaryImpl)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + + void StartCall() override { + // This call initiates two batches, each with a callback + // 1. Send initial metadata + write + writes done + recv initial metadata + // 2. Read message, recv trailing metadata + started_ = true; + + start_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadInitialMetadataDone(ok); + MaybeFinish(); + }, + &start_ops_); + start_ops_.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + start_ops_.RecvInitialMetadata(context_); + start_ops_.set_core_cq_tag(&start_tag_); + call_.PerformOps(&start_ops_); + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void MaybeFinish() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + ::grpc::Status s = std::move(finish_status_); + auto* reactor = reactor_; + auto* call = call_.call(); + this->~ClientCallbackUnaryImpl(); + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + reactor->OnDone(s); + } + } + + private: + friend class ClientCallbackUnaryFactory; + + template + ClientCallbackUnaryImpl(::grpc::internal::Call call, + ::grpc_impl::ClientContext* context, Request* request, + Response* response, + experimental::ClientUnaryReactor* reactor) + : context_(context), call_(call), reactor_(reactor) { + this->BindReactor(reactor); + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(start_ops_.SendMessagePtr(request).ok()); + start_ops_.ClientSendClose(); + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + } + + ::grpc_impl::ClientContext* const context_; + grpc::internal::Call call_; + experimental::ClientUnaryReactor* const reactor_; + + grpc::internal::CallOpSet + start_ops_; + grpc::internal::CallbackWithSuccessTag start_tag_; + + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + ::grpc::Status finish_status_; + + // This call will have 2 callbacks: start and finish + std::atomic callbacks_outstanding_{2}; + bool started_{false}; +}; + +class ClientCallbackUnaryFactory { + public: + template + static void Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const Request* request, Response* response, + experimental::ClientUnaryReactor* reactor) { + grpc::internal::Call call = + channel->CreateCall(method, context, channel->CallbackCQ()); + + ::grpc::g_core_codegen_interface->grpc_call_ref(call.call()); + + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(ClientCallbackUnaryImpl))) + ClientCallbackUnaryImpl(call, context, request, response, reactor); + } +}; + +} // namespace internal +} // namespace grpc_impl +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_context_impl.h b/include/grpcpp/impl/codegen/client_context_impl.h index 8491215cf0e..638ea641bed 100644 --- a/include/grpcpp/impl/codegen/client_context_impl.h +++ b/include/grpcpp/impl/codegen/client_context_impl.h @@ -63,10 +63,19 @@ class ChannelInterface; namespace internal { class RpcMethod; -class CallOpClientRecvStatus; -class CallOpRecvInitialMetadata; template class BlockingUnaryCallImpl; +class CallOpClientRecvStatus; +class CallOpRecvInitialMetadata; +} // namespace internal + +namespace testing { +class InteropClientContextInspector; +} // namespace testing +} // namespace grpc +namespace grpc_impl { + +namespace internal { template class CallbackUnaryCallImpl; template @@ -78,6 +87,10 @@ class ClientCallbackWriterImpl; class ClientCallbackUnaryImpl; } // namespace internal +class CallCredentials; +class Channel; +class CompletionQueue; +class ServerContext; template class ClientReader; template @@ -93,17 +106,6 @@ class ClientAsyncReaderWriter; template class ClientAsyncResponseReader; -namespace testing { -class InteropClientContextInspector; -} // namespace testing -} // namespace grpc -namespace grpc_impl { - -class CallCredentials; -class Channel; -class CompletionQueue; -class ServerContext; - /// Options for \a ClientContext::FromServerContext specifying which traits from /// the \a ServerContext to propagate (copy) from it into a new \a /// ClientContext. @@ -398,30 +400,30 @@ class ClientContext { friend class ::grpc::internal::CallOpRecvInitialMetadata; friend class ::grpc_impl::Channel; template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::ClientAsyncReader; + friend class ::grpc_impl::ClientAsyncReader; template - friend class ::grpc::ClientAsyncWriter; + friend class ::grpc_impl::ClientAsyncWriter; template - friend class ::grpc::ClientAsyncReaderWriter; + friend class ::grpc_impl::ClientAsyncReaderWriter; template - friend class ::grpc::ClientAsyncResponseReader; + friend class ::grpc_impl::ClientAsyncResponseReader; template friend class ::grpc::internal::BlockingUnaryCallImpl; template - friend class ::grpc::internal::CallbackUnaryCallImpl; + friend class ::grpc_impl::internal::CallbackUnaryCallImpl; template - friend class ::grpc::internal::ClientCallbackReaderWriterImpl; + friend class ::grpc_impl::internal::ClientCallbackReaderWriterImpl; template - friend class ::grpc::internal::ClientCallbackReaderImpl; + friend class ::grpc_impl::internal::ClientCallbackReaderImpl; template - friend class ::grpc::internal::ClientCallbackWriterImpl; - friend class ::grpc::internal::ClientCallbackUnaryImpl; + friend class ::grpc_impl::internal::ClientCallbackWriterImpl; + friend class ::grpc_impl::internal::ClientCallbackUnaryImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index 599dd1ecac9..7f80e571c07 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -49,10 +49,10 @@ class BlockingUnaryCallImpl { BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, grpc_impl::ClientContext* context, const InputMessage& request, OutputMessage* result) { - CompletionQueue cq(grpc_completion_queue_attributes{ + ::grpc_impl::CompletionQueue cq(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, nullptr}); // Pluckable completion queue - Call call(channel->CreateCall(method, context, &cq)); + ::grpc::internal::Call call(channel->CreateCall(method, context, &cq)); CallOpSet, CallOpClientSendClose, CallOpClientRecvStatus> diff --git a/include/grpcpp/impl/codegen/completion_queue_impl.h b/include/grpcpp/impl/codegen/completion_queue_impl.h index 0a6b0b0977b..7716a57e84a 100644 --- a/include/grpcpp/impl/codegen/completion_queue_impl.h +++ b/include/grpcpp/impl/codegen/completion_queue_impl.h @@ -47,9 +47,6 @@ class Channel; class Server; class ServerBuilder; class ServerContext; -} // namespace grpc_impl -namespace grpc { - template class ClientReader; template @@ -64,6 +61,8 @@ namespace internal { template class ServerReaderWriterBody; } // namespace internal +} // namespace grpc_impl +namespace grpc { class ChannelInterface; class ServerInterface; @@ -255,17 +254,17 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen { // Friend synchronous wrappers so that they can access Pluck(), which is // a semi-private API geared towards the synchronous implementation. template - friend class ::grpc::ClientReader; + friend class ::grpc_impl::ClientReader; template - friend class ::grpc::ClientWriter; + friend class ::grpc_impl::ClientWriter; template - friend class ::grpc::ClientReaderWriter; + friend class ::grpc_impl::ClientReaderWriter; template - friend class ::grpc::ServerReader; + friend class ::grpc_impl::ServerReader; template - friend class ::grpc::ServerWriter; + friend class ::grpc_impl::ServerWriter; template - friend class ::grpc::internal::ServerReaderWriterBody; + friend class ::grpc_impl::internal::ServerReaderWriterBody; template friend class ::grpc::internal::RpcMethodHandler; template diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 36ae19c5bec..cb771a662b9 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -19,1141 +19,26 @@ #ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H #define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -// Declare base class of all reactors as internal -namespace internal { - -// Forward declarations -template -class CallbackClientStreamingHandler; -template -class CallbackServerStreamingHandler; -template -class CallbackBidiHandler; - -class ServerReactor { - public: - virtual ~ServerReactor() = default; - virtual void OnDone() = 0; - virtual void OnCancel() = 0; - - private: - friend class ::grpc_impl::ServerContext; - template - friend class CallbackClientStreamingHandler; - template - friend class CallbackServerStreamingHandler; - template - friend class CallbackBidiHandler; - - // The ServerReactor is responsible for tracking when it is safe to call - // OnCancel. This function should not be called until after OnStarted is done - // and the RPC has completed with a cancellation. This is tracked by counting - // how many of these conditions have been met and calling OnCancel when none - // remain unmet. - - void MaybeCallOnCancel() { - if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - OnCancel(); - } - } - - std::atomic on_cancel_conditions_remaining_{2}; -}; - -template -class DefaultMessageHolder - : public experimental::MessageHolder { - public: - DefaultMessageHolder() { - this->set_request(&request_obj_); - this->set_response(&response_obj_); - } - void Release() override { - // the object is allocated in the call arena. - this->~DefaultMessageHolder(); - } - - private: - Request request_obj_; - Response response_obj_; -}; - -} // namespace internal - namespace experimental { - -// Forward declarations -template -class ServerReadReactor; -template -class ServerWriteReactor; -template -class ServerBidiReactor; - -// For unary RPCs, the exposed controller class is only an interface -// and the actual implementation is an internal class. -class ServerCallbackRpcController { - public: - virtual ~ServerCallbackRpcController() = default; - - // The method handler must call this function when it is done so that - // the library knows to free its resources - virtual void Finish(Status s) = 0; - - // Allow the method handler to push out the initial metadata before - // the response and status are ready - virtual void SendInitialMetadata(std::function) = 0; - - /// SetCancelCallback passes in a callback to be called when the RPC is - /// canceled for whatever reason (streaming calls have OnCancel instead). This - /// is an advanced and uncommon use with several important restrictions. This - /// function may not be called more than once on the same RPC. - /// - /// If code calls SetCancelCallback on an RPC, it must also call - /// ClearCancelCallback before calling Finish on the RPC controller. That - /// method makes sure that no cancellation callback is executed for this RPC - /// beyond the point of its return. ClearCancelCallback may be called even if - /// SetCancelCallback was not called for this RPC, and it may be called - /// multiple times. It _must_ be called if SetCancelCallback was called for - /// this RPC. - /// - /// The callback should generally be lightweight and nonblocking and primarily - /// concerned with clearing application state related to the RPC or causing - /// operations (such as cancellations) to happen on dependent RPCs. - /// - /// If the RPC is already canceled at the time that SetCancelCallback is - /// called, the callback is invoked immediately. - /// - /// The cancellation callback may be executed concurrently with the method - /// handler that invokes it but will certainly not issue or execute after the - /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the - /// callback is already executing, the callback will complete its execution - /// before ClearCancelCallback takes effect. - /// - /// To preserve the orderings described above, the callback may be called - /// under a lock that is also used for ClearCancelCallback and - /// ServerContext::IsCancelled, so the callback CANNOT call either of those - /// operations on this RPC or any other function that causes those operations - /// to be called before the callback completes. - virtual void SetCancelCallback(std::function callback) = 0; - virtual void ClearCancelCallback() = 0; - - // NOTE: This is an API for advanced users who need custom allocators. - // Get and maybe mutate the allocator state associated with the current RPC. - virtual RpcAllocatorState* GetRpcAllocatorState() = 0; -}; - -// NOTE: The actual streaming object classes are provided -// as API only to support mocking. There are no implementations of -// these class interfaces in the API. -template -class ServerCallbackReader { - public: - virtual ~ServerCallbackReader() {} - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Read(Request* msg) = 0; - - protected: - template - void BindReactor(ServerReadReactor* reactor) { - reactor->InternalBindReader(this); - } -}; - -template -class ServerCallbackWriter { - public: - virtual ~ServerCallbackWriter() {} - - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Write(const Response* msg, WriteOptions options) = 0; - virtual void WriteAndFinish(const Response* msg, WriteOptions options, - Status s) { - // Default implementation that can/should be overridden - Write(msg, std::move(options)); - Finish(std::move(s)); - } - - protected: - template - void BindReactor(ServerWriteReactor* reactor) { - reactor->InternalBindWriter(this); - } -}; - -template -class ServerCallbackReaderWriter { - public: - virtual ~ServerCallbackReaderWriter() {} - - virtual void Finish(Status s) = 0; - virtual void SendInitialMetadata() = 0; - virtual void Read(Request* msg) = 0; - virtual void Write(const Response* msg, WriteOptions options) = 0; - virtual void WriteAndFinish(const Response* msg, WriteOptions options, - Status s) { - // Default implementation that can/should be overridden - Write(msg, std::move(options)); - Finish(std::move(s)); - } - - protected: - void BindReactor(ServerBidiReactor* reactor) { - reactor->InternalBindStream(this); - } -}; - -// The following classes are the reactor interfaces that are to be implemented -// by the user, returned as the result of the method handler for a callback -// method, and activated by the call to OnStarted. The library guarantees that -// OnStarted will be called for any reactor that has been created using a -// method handler registered on a service. No operation initiation method may be -// called until after the call to OnStarted. -// Note that none of the classes are pure; all reactions have a default empty -// reaction so that the user class only needs to override those classes that it -// cares about. - -/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. template -class ServerBidiReactor : public internal::ServerReactor { - public: - ~ServerBidiReactor() = default; - - /// Do NOT call any operation initiation method (names that start with Start) - /// until after the library has called OnStarted on this object. - - /// Send any initial metadata stored in the RPC context. If not invoked, - /// any initial metadata will be passed along with the first Write or the - /// Finish (if there are no writes). - void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } - - /// Initiate a read operation. - /// - /// \param[out] req Where to eventually store the read message. Valid when - /// the library calls OnReadDone - void StartRead(Request* req) { stream_->Read(req); } - - /// Initiate a write operation. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } - - /// Initiate a write operation with specified options. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - void StartWrite(const Response* resp, WriteOptions options) { - stream_->Write(resp, std::move(options)); - } - - /// Initiate a write operation with specified options and final RPC Status, - /// which also causes any trailing metadata for this RPC to be sent out. - /// StartWriteAndFinish is like merging StartWriteLast and Finish into a - /// single step. A key difference, though, is that this operation doesn't have - /// an OnWriteDone reaction - it is considered complete only when OnDone is - /// available. An RPC can either have StartWriteAndFinish or Finish, but not - /// both. - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until Onone, at which point the application - /// regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - /// \param[in] s The status outcome of this RPC - void StartWriteAndFinish(const Response* resp, WriteOptions options, - Status s) { - stream_->WriteAndFinish(resp, std::move(options), std::move(s)); - } - - /// Inform system of a planned write operation with specified options, but - /// allow the library to schedule the actual write coalesced with the writing - /// of trailing metadata (which takes place on a Finish call). - /// - /// \param[in] resp The message to be written. The library takes temporary - /// ownership until OnWriteDone, at which point the - /// application regains ownership of resp. - /// \param[in] options The WriteOptions to use for writing this message - void StartWriteLast(const Response* resp, WriteOptions options) { - StartWrite(resp, std::move(options.set_last_message())); - } - - /// Indicate that the stream is to be finished and the trailing metadata and - /// RPC status are to be sent. Every RPC MUST be finished using either Finish - /// or StartWriteAndFinish (but not both), even if the RPC is already - /// cancelled. - /// - /// \param[in] s The status outcome of this RPC - void Finish(Status s) { stream_->Finish(std::move(s)); } - - /// Notify the application that a streaming RPC has started and that it is now - /// ok to call any operation initiation method. An RPC is considered started - /// after the server has received all initial metadata from the client, which - /// is a result of the client calling StartCall(). - /// - /// \param[in] context The context object now associated with this RPC - virtual void OnStarted(::grpc_impl::ServerContext* context) {} - - /// Notifies the application that an explicit StartSendInitialMetadata - /// operation completed. Not used when the sending of initial metadata - /// piggybacks onto the first write. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnSendInitialMetadataDone(bool ok) {} - - /// Notifies the application that a StartRead operation completed. - /// - /// \param[in] ok Was it successful? If false, no further read-side operation - /// will succeed. - virtual void OnReadDone(bool ok) {} - - /// Notifies the application that a StartWrite (or StartWriteLast) operation - /// completed. - /// - /// \param[in] ok Was it successful? If false, no further write-side operation - /// will succeed. - virtual void OnWriteDone(bool ok) {} - - /// Notifies the application that all operations associated with this RPC - /// have completed. This is an override (from the internal base class) but not - /// final, so derived classes should override it if they want to take action. - void OnDone() override {} - - /// Notifies the application that this RPC has been cancelled. This is an - /// override (from the internal base class) but not final, so derived classes - /// should override it if they want to take action. - void OnCancel() override {} - - private: - friend class ServerCallbackReaderWriter; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindStream( - ServerCallbackReaderWriter* stream) { - stream_ = stream; - } +using ServerReadReactor = + ::grpc_impl::experimental::ServerReadReactor; - ServerCallbackReaderWriter* stream_; -}; - -/// \a ServerReadReactor is the interface for a client-streaming RPC. template -class ServerReadReactor : public internal::ServerReactor { - public: - ~ServerReadReactor() = default; - - /// The following operation initiations are exactly like ServerBidiReactor. - void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } - void StartRead(Request* req) { reader_->Read(req); } - void Finish(Status s) { reader_->Finish(std::move(s)); } - - /// Similar to ServerBidiReactor::OnStarted, except that this also provides - /// the response object that the stream fills in before calling Finish. - /// (It must be filled in if status is OK, but it may be filled in otherwise.) - /// - /// \param[in] context The context object now associated with this RPC - /// \param[in] resp The response object to be used by this RPC - virtual void OnStarted(::grpc_impl::ServerContext* context, Response* resp) {} - - /// The following notifications are exactly like ServerBidiReactor. - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - void OnDone() override {} - void OnCancel() override {} - - private: - friend class ServerCallbackReader; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindReader(ServerCallbackReader* reader) { - reader_ = reader; - } +using ServerWriteReactor = + ::grpc_impl::experimental::ServerWriteReactor; - ServerCallbackReader* reader_; -}; - -/// \a ServerWriteReactor is the interface for a server-streaming RPC. template -class ServerWriteReactor : public internal::ServerReactor { - public: - ~ServerWriteReactor() = default; - - /// The following operation initiations are exactly like ServerBidiReactor. - void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } - void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } - void StartWrite(const Response* resp, WriteOptions options) { - writer_->Write(resp, std::move(options)); - } - void StartWriteAndFinish(const Response* resp, WriteOptions options, - Status s) { - writer_->WriteAndFinish(resp, std::move(options), std::move(s)); - } - void StartWriteLast(const Response* resp, WriteOptions options) { - StartWrite(resp, std::move(options.set_last_message())); - } - void Finish(Status s) { writer_->Finish(std::move(s)); } - - /// Similar to ServerBidiReactor::OnStarted, except that this also provides - /// the request object sent by the client. - /// - /// \param[in] context The context object now associated with this RPC - /// \param[in] req The request object sent by the client - virtual void OnStarted(::grpc_impl::ServerContext* context, - const Request* req) {} - - /// The following notifications are exactly like ServerBidiReactor. - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - void OnDone() override {} - void OnCancel() override {} +using ServerBidiReactor = + ::grpc_impl::experimental::ServerBidiReactor; - private: - friend class ServerCallbackWriter; - // May be overridden by internal implementation details. This is not a public - // customization point. - virtual void InternalBindWriter(ServerCallbackWriter* writer) { - writer_ = writer; - } - - ServerCallbackWriter* writer_; -}; +typedef ::grpc_impl::experimental::ServerCallbackRpcController + ServerCallbackRpcController; } // namespace experimental - -namespace internal { - -template -class UnimplementedReadReactor - : public experimental::ServerReadReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*, Response*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class UnimplementedWriteReactor - : public experimental::ServerWriteReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*, const Request*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class UnimplementedBidiReactor - : public experimental::ServerBidiReactor { - public: - void OnDone() override { delete this; } - void OnStarted(::grpc_impl::ServerContext*) override { - this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); - } -}; - -template -class CallbackUnaryHandler : public MethodHandler { - public: - CallbackUnaryHandler( - std::function - func) - : func_(func) {} - - void SetMessageAllocator( - experimental::MessageAllocator* allocator) { - allocator_ = allocator; - } - - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a controller structure (that includes request/response) - g_core_codegen_interface->grpc_call_ref(param.call->call()); - auto* allocator_state = - static_cast*>( - param.internal_data); - auto* controller = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) - ServerCallbackRpcControllerImpl(param.server_context, param.call, - allocator_state, - std::move(param.call_requester)); - Status status = param.status; - if (status.ok()) { - // Call the actual function handler and expect the user to call finish - CatchingCallback(func_, param.server_context, controller->request(), - controller->response(), controller); - } else { - // if deserialization failed, we need to fail the call - controller->Finish(status); - } - } - - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, - void** handler_data) final { - ByteBuffer buf; - buf.set_buffer(req); - RequestType* request = nullptr; - experimental::MessageHolder* allocator_state = - nullptr; - if (allocator_ != nullptr) { - allocator_state = allocator_->AllocateMessages(); - } else { - allocator_state = new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(DefaultMessageHolder))) - DefaultMessageHolder(); - } - *handler_data = allocator_state; - request = allocator_state->request(); - *status = SerializationTraits::Deserialize(&buf, request); - buf.Release(); - if (status->ok()) { - return request; - } - // Clean up on deserialization failure. - allocator_state->Release(); - return nullptr; - } - - private: - std::function - func_; - experimental::MessageAllocator* allocator_ = - nullptr; - - // The implementation class of ServerCallbackRpcController is a private member - // of CallbackUnaryHandler since it is never exposed anywhere, and this allows - // it to take advantage of CallbackUnaryHandler's friendships. - class ServerCallbackRpcControllerImpl - : public experimental::ServerCallbackRpcController { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (s.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(response())); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - } - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata(std::function f) override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 - // and if performance of this operation matters - meta_tag_.Set(call_.call(), - [this, f](bool ok) { - f(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - // Neither SetCancelCallback nor ClearCancelCallback should affect the - // callbacks_outstanding_ count since they are paired and both must precede - // the invocation of Finish (if they are used at all) - void SetCancelCallback(std::function callback) override { - ctx_->SetCancelCallback(std::move(callback)); - } - - void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } - - experimental::RpcAllocatorState* GetRpcAllocatorState() override { - return allocator_state_; - } - - private: - friend class CallbackUnaryHandler; - - ServerCallbackRpcControllerImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - experimental::MessageHolder* allocator_state, - std::function call_requester) - : ctx_(ctx), - call_(*call), - allocator_state_(allocator_state), - call_requester_(std::move(call_requester)) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); - } - - const RequestType* request() { return allocator_state_->request(); } - ResponseType* response() { return allocator_state_->response(); } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - allocator_state_->Release(); - this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - experimental::MessageHolder* const - allocator_state_; - std::function call_requester_; - std::atomic callbacks_outstanding_{ - 2}; // reserve for Finish and CompletionOp - }; -}; - -template -class CallbackClientStreamingHandler : public MethodHandler { - public: - CallbackClientStreamingHandler( - std::function< - experimental::ServerReadReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a reader structure (that includes response) - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerReadReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerReadReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedReadReactor; - } - - auto* reader = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackReaderImpl))) - ServerCallbackReaderImpl(param.server_context, param.call, - std::move(param.call_requester), reactor); - - reader->BindReactor(reactor); - reactor->OnStarted(param.server_context, reader->response()); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - reader->MaybeDone(); - } - - private: - std::function*()> - func_; - - class ServerCallbackReaderImpl - : public experimental::ServerCallbackReader { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (s.ok()) { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, - finish_ops_.SendMessagePtr(&resp_)); - } else { - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - } - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Read(RequestType* req) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - read_ops_.RecvMessage(req); - call_.PerformOps(&read_ops_); - } - - private: - friend class CallbackClientStreamingHandler; - - ServerCallbackReaderImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - std::function call_requester, - experimental::ServerReadReactor* reactor) - : ctx_(ctx), - call_(*call), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeDone(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - } - - ~ServerCallbackReaderImpl() {} - - ResponseType* response() { return &resp_; } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackReaderImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - ResponseType resp_; - std::function call_requester_; - experimental::ServerReadReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -template -class CallbackServerStreamingHandler : public MethodHandler { - public: - CallbackServerStreamingHandler( - std::function< - experimental::ServerWriteReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - // Arena allocate a writer structure - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerWriteReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerWriteReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedWriteReactor; - } - - auto* writer = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackWriterImpl))) - ServerCallbackWriterImpl(param.server_context, param.call, - static_cast(param.request), - std::move(param.call_requester), reactor); - writer->BindReactor(reactor); - reactor->OnStarted(param.server_context, writer->request()); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - writer->MaybeDone(); - } - - void* Deserialize(grpc_call* call, grpc_byte_buffer* req, Status* status, - void** handler_data) final { - ByteBuffer buf; - buf.set_buffer(req); - auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc( - call, sizeof(RequestType))) RequestType(); - *status = SerializationTraits::Deserialize(&buf, request); - buf.Release(); - if (status->ok()) { - return request; - } - request->~RequestType(); - return nullptr; - } - - private: - std::function*()> - func_; - - class ServerCallbackWriterImpl - : public experimental::ServerCallbackWriter { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - finish_ops_.set_core_cq_tag(&finish_tag_); - - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - write_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WriteAndFinish(const ResponseType* resp, WriteOptions options, - Status s) override { - // This combines the write into the finish callback - // Don't send any message if the status is bad - if (s.ok()) { - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); - } - Finish(std::move(s)); - } - - private: - friend class CallbackServerStreamingHandler; - - ServerCallbackWriterImpl( - ::grpc_impl::ServerContext* ctx, Call* call, const RequestType* req, - std::function call_requester, - experimental::ServerWriteReactor* reactor) - : ctx_(ctx), - call_(*call), - req_(req), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeDone(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - } - ~ServerCallbackWriterImpl() { req_->~RequestType(); } - - const RequestType* request() { return req_; } - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackWriterImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet write_ops_; - CallbackWithSuccessTag write_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - const RequestType* req_; - std::function call_requester_; - experimental::ServerWriteReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -template -class CallbackBidiHandler : public MethodHandler { - public: - CallbackBidiHandler( - std::function< - experimental::ServerBidiReactor*()> - func) - : func_(std::move(func)) {} - void RunHandler(const HandlerParameter& param) final { - g_core_codegen_interface->grpc_call_ref(param.call->call()); - - experimental::ServerBidiReactor* reactor = - param.status.ok() - ? CatchingReactorCreator< - experimental::ServerBidiReactor>( - func_) - : nullptr; - - if (reactor == nullptr) { - // if deserialization or reactor creator failed, we need to fail the call - reactor = new UnimplementedBidiReactor; - } - - auto* stream = new (g_core_codegen_interface->grpc_call_arena_alloc( - param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) - ServerCallbackReaderWriterImpl(param.server_context, param.call, - std::move(param.call_requester), - reactor); - - stream->BindReactor(reactor); - reactor->OnStarted(param.server_context); - // The earliest that OnCancel can be called is after OnStarted is done. - reactor->MaybeCallOnCancel(); - stream->MaybeDone(); - } - - private: - std::function*()> - func_; - - class ServerCallbackReaderWriterImpl - : public experimental::ServerCallbackReaderWriter { - public: - void Finish(Status s) override { - finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, - &finish_ops_); - finish_ops_.set_core_cq_tag(&finish_tag_); - - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - finish_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); - call_.PerformOps(&finish_ops_); - } - - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - meta_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnSendInitialMetadataDone(ok); - MaybeDone(); - }, - &meta_ops_); - meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - meta_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - meta_ops_.set_core_cq_tag(&meta_tag_); - call_.PerformOps(&meta_ops_); - } - - void Write(const ResponseType* resp, WriteOptions options) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - write_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); - call_.PerformOps(&write_ops_); - } - - void WriteAndFinish(const ResponseType* resp, WriteOptions options, - Status s) override { - // Don't send any message if the status is bad - if (s.ok()) { - // TODO(vjpai): don't assert - GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); - } - Finish(std::move(s)); - } - - void Read(RequestType* req) override { - callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); - read_ops_.RecvMessage(req); - call_.PerformOps(&read_ops_); - } - - private: - friend class CallbackBidiHandler; - - ServerCallbackReaderWriterImpl( - ::grpc_impl::ServerContext* ctx, Call* call, - std::function call_requester, - experimental::ServerBidiReactor* reactor) - : ctx_(ctx), - call_(*call), - call_requester_(std::move(call_requester)), - reactor_(reactor) { - ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); - write_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnWriteDone(ok); - MaybeDone(); - }, - &write_ops_); - write_ops_.set_core_cq_tag(&write_tag_); - read_tag_.Set(call_.call(), - [this](bool ok) { - reactor_->OnReadDone(ok); - MaybeDone(); - }, - &read_ops_); - read_ops_.set_core_cq_tag(&read_tag_); - } - ~ServerCallbackReaderWriterImpl() {} - - void MaybeDone() { - if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( - 1, std::memory_order_acq_rel) == 1)) { - reactor_->OnDone(); - grpc_call* call = call_.call(); - auto call_requester = std::move(call_requester_); - this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor - g_core_codegen_interface->grpc_call_unref(call); - call_requester(); - } - } - - CallOpSet meta_ops_; - CallbackWithSuccessTag meta_tag_; - CallOpSet - finish_ops_; - CallbackWithSuccessTag finish_tag_; - CallOpSet write_ops_; - CallbackWithSuccessTag write_tag_; - CallOpSet> read_ops_; - CallbackWithSuccessTag read_tag_; - - ::grpc_impl::ServerContext* ctx_; - Call call_; - std::function call_requester_; - experimental::ServerBidiReactor* reactor_; - std::atomic callbacks_outstanding_{ - 3}; // reserve for OnStarted, Finish, and CompletionOp - }; -}; - -} // namespace internal - } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/server_callback_impl.h b/include/grpcpp/impl/codegen/server_callback_impl.h new file mode 100644 index 00000000000..08ecdfd6497 --- /dev/null +++ b/include/grpcpp/impl/codegen/server_callback_impl.h @@ -0,0 +1,1186 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H +#define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +// Declare base class of all reactors as internal +namespace internal { + +// Forward declarations +template +class CallbackClientStreamingHandler; +template +class CallbackServerStreamingHandler; +template +class CallbackBidiHandler; + +class ServerReactor { + public: + virtual ~ServerReactor() = default; + virtual void OnDone() = 0; + virtual void OnCancel() = 0; + + private: + friend class ::grpc_impl::ServerContext; + template + friend class CallbackClientStreamingHandler; + template + friend class CallbackServerStreamingHandler; + template + friend class CallbackBidiHandler; + + // The ServerReactor is responsible for tracking when it is safe to call + // OnCancel. This function should not be called until after OnStarted is done + // and the RPC has completed with a cancellation. This is tracked by counting + // how many of these conditions have been met and calling OnCancel when none + // remain unmet. + + void MaybeCallOnCancel() { + if (GPR_UNLIKELY(on_cancel_conditions_remaining_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + OnCancel(); + } + } + + std::atomic on_cancel_conditions_remaining_{2}; +}; + +template +class DefaultMessageHolder + : public ::grpc::experimental::MessageHolder { + public: + DefaultMessageHolder() { + this->set_request(&request_obj_); + this->set_response(&response_obj_); + } + void Release() override { + // the object is allocated in the call arena. + this->~DefaultMessageHolder(); + } + + private: + Request request_obj_; + Response response_obj_; +}; + +} // namespace internal + +namespace experimental { + +// Forward declarations +template +class ServerReadReactor; +template +class ServerWriteReactor; +template +class ServerBidiReactor; + +// For unary RPCs, the exposed controller class is only an interface +// and the actual implementation is an internal class. +class ServerCallbackRpcController { + public: + virtual ~ServerCallbackRpcController() = default; + + // The method handler must call this function when it is done so that + // the library knows to free its resources + virtual void Finish(::grpc::Status s) = 0; + + // Allow the method handler to push out the initial metadata before + // the response and status are ready + virtual void SendInitialMetadata(std::function) = 0; + + /// SetCancelCallback passes in a callback to be called when the RPC is + /// canceled for whatever reason (streaming calls have OnCancel instead). This + /// is an advanced and uncommon use with several important restrictions. This + /// function may not be called more than once on the same RPC. + /// + /// If code calls SetCancelCallback on an RPC, it must also call + /// ClearCancelCallback before calling Finish on the RPC controller. That + /// method makes sure that no cancellation callback is executed for this RPC + /// beyond the point of its return. ClearCancelCallback may be called even if + /// SetCancelCallback was not called for this RPC, and it may be called + /// multiple times. It _must_ be called if SetCancelCallback was called for + /// this RPC. + /// + /// The callback should generally be lightweight and nonblocking and primarily + /// concerned with clearing application state related to the RPC or causing + /// operations (such as cancellations) to happen on dependent RPCs. + /// + /// If the RPC is already canceled at the time that SetCancelCallback is + /// called, the callback is invoked immediately. + /// + /// The cancellation callback may be executed concurrently with the method + /// handler that invokes it but will certainly not issue or execute after the + /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the + /// callback is already executing, the callback will complete its execution + /// before ClearCancelCallback takes effect. + /// + /// To preserve the orderings described above, the callback may be called + /// under a lock that is also used for ClearCancelCallback and + /// ServerContext::IsCancelled, so the callback CANNOT call either of those + /// operations on this RPC or any other function that causes those operations + /// to be called before the callback completes. + virtual void SetCancelCallback(std::function callback) = 0; + virtual void ClearCancelCallback() = 0; + + // NOTE: This is an API for advanced users who need custom allocators. + // Get and maybe mutate the allocator state associated with the current RPC. + virtual grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() = 0; +}; + +// NOTE: The actual streaming object classes are provided +// as API only to support mocking. There are no implementations of +// these class interfaces in the API. +template +class ServerCallbackReader { + public: + virtual ~ServerCallbackReader() {} + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + + protected: + template + void BindReactor(ServerReadReactor* reactor) { + reactor->InternalBindReader(this); + } +}; + +template +class ServerCallbackWriter { + public: + virtual ~ServerCallbackWriter() {} + + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Write(const Response* msg, ::grpc::WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, ::grpc::WriteOptions options, + ::grpc::Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + template + void BindReactor(ServerWriteReactor* reactor) { + reactor->InternalBindWriter(this); + } +}; + +template +class ServerCallbackReaderWriter { + public: + virtual ~ServerCallbackReaderWriter() {} + + virtual void Finish(::grpc::Status s) = 0; + virtual void SendInitialMetadata() = 0; + virtual void Read(Request* msg) = 0; + virtual void Write(const Response* msg, ::grpc::WriteOptions options) = 0; + virtual void WriteAndFinish(const Response* msg, ::grpc::WriteOptions options, + ::grpc::Status s) { + // Default implementation that can/should be overridden + Write(msg, std::move(options)); + Finish(std::move(s)); + } + + protected: + void BindReactor(ServerBidiReactor* reactor) { + reactor->InternalBindStream(this); + } +}; + +// The following classes are the reactor interfaces that are to be implemented +// by the user, returned as the result of the method handler for a callback +// method, and activated by the call to OnStarted. The library guarantees that +// OnStarted will be called for any reactor that has been created using a +// method handler registered on a service. No operation initiation method may be +// called until after the call to OnStarted. +// Note that none of the classes are pure; all reactions have a default empty +// reaction so that the user class only needs to override those classes that it +// cares about. + +/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. +template +class ServerBidiReactor : public internal::ServerReactor { + public: + ~ServerBidiReactor() = default; + + /// Do NOT call any operation initiation method (names that start with Start) + /// until after the library has called OnStarted on this object. + + /// Send any initial metadata stored in the RPC context. If not invoked, + /// any initial metadata will be passed along with the first Write or the + /// Finish (if there are no writes). + void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } + + /// Initiate a read operation. + /// + /// \param[out] req Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Request* req) { stream_->Read(req); } + + /// Initiate a write operation. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + void StartWrite(const Response* resp) { + StartWrite(resp, ::grpc::WriteOptions()); + } + + /// Initiate a write operation with specified options. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Response* resp, ::grpc::WriteOptions options) { + stream_->Write(resp, std::move(options)); + } + + /// Initiate a write operation with specified options and final RPC Status, + /// which also causes any trailing metadata for this RPC to be sent out. + /// StartWriteAndFinish is like merging StartWriteLast and Finish into a + /// single step. A key difference, though, is that this operation doesn't have + /// an OnWriteDone reaction - it is considered complete only when OnDone is + /// available. An RPC can either have StartWriteAndFinish or Finish, but not + /// both. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until Onone, at which point the application + /// regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + /// \param[in] s The status outcome of this RPC + void StartWriteAndFinish(const Response* resp, ::grpc::WriteOptions options, + ::grpc::Status s) { + stream_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + + /// Inform system of a planned write operation with specified options, but + /// allow the library to schedule the actual write coalesced with the writing + /// of trailing metadata (which takes place on a Finish call). + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + + /// Indicate that the stream is to be finished and the trailing metadata and + /// RPC status are to be sent. Every RPC MUST be finished using either Finish + /// or StartWriteAndFinish (but not both), even if the RPC is already + /// cancelled. + /// + /// \param[in] s The status outcome of this RPC + void Finish(::grpc::Status s) { stream_->Finish(std::move(s)); } + + /// Notify the application that a streaming RPC has started and that it is now + /// ok to call any operation initiation method. An RPC is considered started + /// after the server has received all initial metadata from the client, which + /// is a result of the client calling StartCall(). + /// + /// \param[in] context The context object now associated with this RPC + virtual void OnStarted(::grpc_impl::ServerContext* context) {} + + /// Notifies the application that an explicit StartSendInitialMetadata + /// operation completed. Not used when the sending of initial metadata + /// piggybacks onto the first write. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnSendInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite (or StartWriteLast) operation + /// completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that all operations associated with this RPC + /// have completed. This is an override (from the internal base class) but not + /// final, so derived classes should override it if they want to take action. + void OnDone() override {} + + /// Notifies the application that this RPC has been cancelled. This is an + /// override (from the internal base class) but not final, so derived classes + /// should override it if they want to take action. + void OnCancel() override {} + + private: + friend class ServerCallbackReaderWriter; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindStream( + ServerCallbackReaderWriter* stream) { + stream_ = stream; + } + + ServerCallbackReaderWriter* stream_; +}; + +/// \a ServerReadReactor is the interface for a client-streaming RPC. +template +class ServerReadReactor : public internal::ServerReactor { + public: + ~ServerReadReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } + void StartRead(Request* req) { reader_->Read(req); } + void Finish(::grpc::Status s) { reader_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the response object that the stream fills in before calling Finish. + /// (It must be filled in if status is OK, but it may be filled in otherwise.) + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] resp The response object to be used by this RPC + virtual void OnStarted(::grpc_impl::ServerContext* context, Response* resp) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackReader; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindReader(ServerCallbackReader* reader) { + reader_ = reader; + } + + ServerCallbackReader* reader_; +}; + +/// \a ServerWriteReactor is the interface for a server-streaming RPC. +template +class ServerWriteReactor : public internal::ServerReactor { + public: + ~ServerWriteReactor() = default; + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } + void StartWrite(const Response* resp) { + StartWrite(resp, ::grpc::WriteOptions()); + } + void StartWrite(const Response* resp, ::grpc::WriteOptions options) { + writer_->Write(resp, std::move(options)); + } + void StartWriteAndFinish(const Response* resp, ::grpc::WriteOptions options, + ::grpc::Status s) { + writer_->WriteAndFinish(resp, std::move(options), std::move(s)); + } + void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); + } + void Finish(::grpc::Status s) { writer_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the request object sent by the client. + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] req The request object sent by the client + virtual void OnStarted(::grpc_impl::ServerContext* context, + const Request* req) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} + + private: + friend class ServerCallbackWriter; + // May be overridden by internal implementation details. This is not a public + // customization point. + virtual void InternalBindWriter(ServerCallbackWriter* writer) { + writer_ = writer; + } + + ServerCallbackWriter* writer_; +}; + +} // namespace experimental + +namespace internal { + +template +class UnimplementedReadReactor + : public experimental::ServerReadReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*, Response*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedWriteReactor + : public experimental::ServerWriteReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*, const Request*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class UnimplementedBidiReactor + : public experimental::ServerBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(::grpc_impl::ServerContext*) override { + this->Finish(::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "")); + } +}; + +template +class CallbackUnaryHandler : public grpc::internal::MethodHandler { + public: + CallbackUnaryHandler( + std::function + func) + : func_(func) {} + + void SetMessageAllocator( + ::grpc::experimental::MessageAllocator* + allocator) { + allocator_ = allocator; + } + + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a controller structure (that includes request/response) + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + auto* allocator_state = static_cast< + grpc::experimental::MessageHolder*>( + param.internal_data); + auto* controller = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackRpcControllerImpl))) + ServerCallbackRpcControllerImpl(param.server_context, param.call, + allocator_state, + std::move(param.call_requester)); + ::grpc::Status status = param.status; + if (status.ok()) { + // Call the actual function handler and expect the user to call finish + grpc::internal::CatchingCallback(func_, param.server_context, + controller->request(), + controller->response(), controller); + } else { + // if deserialization failed, we need to fail the call + controller->Finish(status); + } + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, + ::grpc::Status* status, void** handler_data) final { + grpc::ByteBuffer buf; + buf.set_buffer(req); + RequestType* request = nullptr; + ::grpc::experimental::MessageHolder* + allocator_state = nullptr; + if (allocator_ != nullptr) { + allocator_state = allocator_->AllocateMessages(); + } else { + allocator_state = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(DefaultMessageHolder))) + DefaultMessageHolder(); + } + *handler_data = allocator_state; + request = allocator_state->request(); + *status = + ::grpc::SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + // Clean up on deserialization failure. + allocator_state->Release(); + return nullptr; + } + + private: + std::function + func_; + grpc::experimental::MessageAllocator* allocator_ = + nullptr; + + // The implementation class of ServerCallbackRpcController is a private member + // of CallbackUnaryHandler since it is never exposed anywhere, and this allows + // it to take advantage of CallbackUnaryHandler's friendships. + class ServerCallbackRpcControllerImpl + : public experimental::ServerCallbackRpcController { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(response())); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata(std::function f) override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14 + // and if performance of this operation matters + meta_tag_.Set(call_.call(), + [this, f](bool ok) { + f(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + // Neither SetCancelCallback nor ClearCancelCallback should affect the + // callbacks_outstanding_ count since they are paired and both must precede + // the invocation of Finish (if they are used at all) + void SetCancelCallback(std::function callback) override { + ctx_->SetCancelCallback(std::move(callback)); + } + + void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } + + grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() override { + return allocator_state_; + } + + private: + friend class CallbackUnaryHandler; + + ServerCallbackRpcControllerImpl( + ServerContext* ctx, ::grpc::internal::Call* call, + ::grpc::experimental::MessageHolder* + allocator_state, + std::function call_requester) + : ctx_(ctx), + call_(*call), + allocator_state_(allocator_state), + call_requester_(std::move(call_requester)) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr); + } + + const RequestType* request() { return allocator_state_->request(); } + ResponseType* response() { return allocator_state_->response(); } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + allocator_state_->Release(); + this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + grpc::experimental::MessageHolder* const + allocator_state_; + std::function call_requester_; + std::atomic callbacks_outstanding_{ + 2}; // reserve for Finish and CompletionOp + }; +}; + +template +class CallbackClientStreamingHandler : public grpc::internal::MethodHandler { + public: + CallbackClientStreamingHandler( + std::function< + experimental::ServerReadReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a reader structure (that includes response) + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerReadReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerReadReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedReadReactor; + } + + auto* reader = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderImpl))) + ServerCallbackReaderImpl(param.server_context, param.call, + std::move(param.call_requester), reactor); + + reader->BindReactor(reactor); + reactor->OnStarted(param.server_context, reader->response()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + reader->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderImpl + : public experimental::ServerCallbackReader { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // The response is dropped if the status is not OK. + if (s.ok()) { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, + finish_ops_.SendMessagePtr(&resp_)); + } else { + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + } + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Read(RequestType* req) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackClientStreamingHandler; + + ServerCallbackReaderImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + std::function call_requester, + experimental::ServerReadReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + + ~ServerCallbackReaderImpl() {} + + ResponseType* response() { return &resp_; } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + ResponseType resp_; + std::function call_requester_; + experimental::ServerReadReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackServerStreamingHandler : public grpc::internal::MethodHandler { + public: + CallbackServerStreamingHandler( + std::function< + experimental::ServerWriteReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + // Arena allocate a writer structure + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerWriteReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerWriteReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedWriteReactor; + } + + auto* writer = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackWriterImpl))) + ServerCallbackWriterImpl(param.server_context, param.call, + static_cast(param.request), + std::move(param.call_requester), reactor); + writer->BindReactor(reactor); + reactor->OnStarted(param.server_context, writer->request()); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + writer->MaybeDone(); + } + + void* Deserialize(grpc_call* call, grpc_byte_buffer* req, + ::grpc::Status* status, void** handler_data) final { + ::grpc::ByteBuffer buf; + buf.set_buffer(req); + auto* request = + new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + call, sizeof(RequestType))) RequestType(); + *status = + ::grpc::SerializationTraits::Deserialize(&buf, request); + buf.Release(); + if (status->ok()) { + return request; + } + request->~RequestType(); + return nullptr; + } + + private: + std::function*()> + func_; + + class ServerCallbackWriterImpl + : public experimental::ServerCallbackWriter { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, + ::grpc::WriteOptions options) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, ::grpc::WriteOptions options, + ::grpc::Status s) override { + // This combines the write into the finish callback + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); + } + + private: + friend class CallbackServerStreamingHandler; + + ServerCallbackWriterImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + const RequestType* req, std::function call_requester, + experimental::ServerWriteReactor* reactor) + : ctx_(ctx), + call_(*call), + req_(req), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + } + ~ServerCallbackWriterImpl() { req_->~RequestType(); } + + const RequestType* request() { return req_; } + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackWriterImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + const RequestType* req_; + std::function call_requester_; + experimental::ServerWriteReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +template +class CallbackBidiHandler : public grpc::internal::MethodHandler { + public: + CallbackBidiHandler( + std::function< + experimental::ServerBidiReactor*()> + func) + : func_(std::move(func)) {} + void RunHandler(const HandlerParameter& param) final { + ::grpc::g_core_codegen_interface->grpc_call_ref(param.call->call()); + + experimental::ServerBidiReactor* reactor = + param.status.ok() + ? ::grpc::internal::CatchingReactorCreator< + experimental::ServerBidiReactor>( + func_) + : nullptr; + + if (reactor == nullptr) { + // if deserialization or reactor creator failed, we need to fail the call + reactor = new UnimplementedBidiReactor; + } + + auto* stream = new (::grpc::g_core_codegen_interface->grpc_call_arena_alloc( + param.call->call(), sizeof(ServerCallbackReaderWriterImpl))) + ServerCallbackReaderWriterImpl(param.server_context, param.call, + std::move(param.call_requester), + reactor); + + stream->BindReactor(reactor); + reactor->OnStarted(param.server_context); + // The earliest that OnCancel can be called is after OnStarted is done. + reactor->MaybeCallOnCancel(); + stream->MaybeDone(); + } + + private: + std::function*()> + func_; + + class ServerCallbackReaderWriterImpl + : public experimental::ServerCallbackReaderWriter { + public: + void Finish(::grpc::Status s) override { + finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); }, + &finish_ops_); + finish_ops_.set_core_cq_tag(&finish_tag_); + + if (!ctx_->sent_initial_metadata_) { + finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s); + call_.PerformOps(&finish_ops_); + } + + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + meta_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnSendInitialMetadataDone(ok); + MaybeDone(); + }, + &meta_ops_); + meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + meta_ops_.set_core_cq_tag(&meta_tag_); + call_.PerformOps(&meta_ops_); + } + + void Write(const ResponseType* resp, + ::grpc::WriteOptions options) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->sent_initial_metadata_) { + write_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + write_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(write_ops_.SendMessagePtr(resp, options).ok()); + call_.PerformOps(&write_ops_); + } + + void WriteAndFinish(const ResponseType* resp, ::grpc::WriteOptions options, + ::grpc::Status s) override { + // Don't send any message if the status is bad + if (s.ok()) { + // TODO(vjpai): don't assert + GPR_CODEGEN_ASSERT(finish_ops_.SendMessagePtr(resp, options).ok()); + } + Finish(std::move(s)); + } + + void Read(RequestType* req) override { + callbacks_outstanding_.fetch_add(1, std::memory_order_relaxed); + read_ops_.RecvMessage(req); + call_.PerformOps(&read_ops_); + } + + private: + friend class CallbackBidiHandler; + + ServerCallbackReaderWriterImpl( + ::grpc_impl::ServerContext* ctx, grpc::internal::Call* call, + std::function call_requester, + experimental::ServerBidiReactor* reactor) + : ctx_(ctx), + call_(*call), + call_requester_(std::move(call_requester)), + reactor_(reactor) { + ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor); + write_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnWriteDone(ok); + MaybeDone(); + }, + &write_ops_); + write_ops_.set_core_cq_tag(&write_tag_); + read_tag_.Set(call_.call(), + [this](bool ok) { + reactor_->OnReadDone(ok); + MaybeDone(); + }, + &read_ops_); + read_ops_.set_core_cq_tag(&read_tag_); + } + ~ServerCallbackReaderWriterImpl() {} + + void MaybeDone() { + if (GPR_UNLIKELY(callbacks_outstanding_.fetch_sub( + 1, std::memory_order_acq_rel) == 1)) { + reactor_->OnDone(); + grpc_call* call = call_.call(); + auto call_requester = std::move(call_requester_); + this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor + ::grpc::g_core_codegen_interface->grpc_call_unref(call); + call_requester(); + } + } + + grpc::internal::CallOpSet + meta_ops_; + grpc::internal::CallbackWithSuccessTag meta_tag_; + grpc::internal::CallOpSet + finish_ops_; + grpc::internal::CallbackWithSuccessTag finish_tag_; + grpc::internal::CallOpSet + write_ops_; + grpc::internal::CallbackWithSuccessTag write_tag_; + grpc::internal::CallOpSet> + read_ops_; + grpc::internal::CallbackWithSuccessTag read_tag_; + + ::grpc_impl::ServerContext* ctx_; + grpc::internal::Call call_; + std::function call_requester_; + experimental::ServerBidiReactor* reactor_; + std::atomic callbacks_outstanding_{ + 3}; // reserve for OnStarted, Finish, and CompletionOp + }; +}; + +} // namespace internal + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_IMPL_H diff --git a/include/grpcpp/impl/codegen/server_context_impl.h b/include/grpcpp/impl/codegen/server_context_impl.h index 9497735eacc..72137f153b1 100644 --- a/include/grpcpp/impl/codegen/server_context_impl.h +++ b/include/grpcpp/impl/codegen/server_context_impl.h @@ -44,10 +44,6 @@ namespace grpc_impl { class ClientContext; class CompletionQueue; class Server; -} // namespace grpc_impl -namespace grpc { -class GenericServerContext; -class ServerInterface; template class ServerAsyncReader; template @@ -62,14 +58,6 @@ template class ServerWriter; namespace internal { -template -class ServerReaderWriterBody; -template -class RpcMethodHandler; -template -class ClientStreamingHandler; -template -class ServerStreamingHandler; template class BidiStreamingHandler; template @@ -80,12 +68,28 @@ template class CallbackServerStreamingHandler; template class CallbackBidiHandler; +template +class ServerReaderWriterBody; +class ServerReactor; +} // namespace internal + +} // namespace grpc_impl +namespace grpc { +class GenericServerContext; +class ServerInterface; + +namespace internal { +template +class ClientStreamingHandler; +template +class ServerStreamingHandler; +template +class RpcMethodHandler; template class TemplatedBidiStreamingHandler; template class ErrorMethodHandler; class Call; -class ServerReactor; } // namespace internal class ServerInterface; @@ -275,19 +279,19 @@ class ServerContext { friend class ::grpc::ServerInterface; friend class ::grpc_impl::Server; template - friend class ::grpc::ServerAsyncReader; + friend class ::grpc_impl::ServerAsyncReader; template - friend class ::grpc::ServerAsyncWriter; + friend class ::grpc_impl::ServerAsyncWriter; template - friend class ::grpc::ServerAsyncResponseWriter; + friend class ::grpc_impl::ServerAsyncResponseWriter; template - friend class ::grpc::ServerAsyncReaderWriter; + friend class ::grpc_impl::ServerAsyncReaderWriter; template - friend class ::grpc::ServerReader; + friend class ::grpc_impl::ServerReader; template - friend class ::grpc::ServerWriter; + friend class ::grpc_impl::ServerWriter; template - friend class ::grpc::internal::ServerReaderWriterBody; + friend class ::grpc_impl::internal::ServerReaderWriterBody; template friend class ::grpc::internal::RpcMethodHandler; template @@ -297,13 +301,13 @@ class ServerContext { template friend class ::grpc::internal::TemplatedBidiStreamingHandler; template - friend class ::grpc::internal::CallbackUnaryHandler; + friend class ::grpc_impl::internal::CallbackUnaryHandler; template - friend class ::grpc::internal::CallbackClientStreamingHandler; + friend class ::grpc_impl::internal::CallbackClientStreamingHandler; template - friend class ::grpc::internal::CallbackServerStreamingHandler; + friend class ::grpc_impl::internal::CallbackServerStreamingHandler; template - friend class ::grpc::internal::CallbackBidiHandler; + friend class ::grpc_impl::internal::CallbackBidiHandler; template <::grpc::StatusCode code> friend class ::grpc::internal::ErrorMethodHandler; friend class ::grpc_impl::ClientContext; @@ -317,7 +321,7 @@ class ServerContext { void BeginCompletionOp(::grpc::internal::Call* call, std::function callback, - ::grpc::internal::ServerReactor* reactor); + ::grpc_impl::internal::ServerReactor* reactor); /// Return the tag queued by BeginCompletionOp() ::grpc::internal::CompletionQueueTag* GetCompletionOpTag(); diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 4109ee1b504..f13dfb99fa0 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -149,8 +149,9 @@ class Service { void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context, Message* request, internal::ServerAsyncStreamingInterface* stream, - CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, + void* tag) { // Typecast the index to size_t for indexing into a vector // while preserving the API that existed before a compiler // warning was first seen (grpc/grpc#11664) @@ -160,8 +161,9 @@ class Service { } void RequestAsyncClientStreaming( int index, ::grpc_impl::ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); @@ -169,16 +171,18 @@ class Service { template void RequestAsyncServerStreaming( int index, ::grpc_impl::ServerContext* context, Message* request, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncBidiStreaming( int index, ::grpc_impl::ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag) { + internal::ServerAsyncStreamingInterface* stream, + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { size_t idx = static_cast(index); server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 9d030a13a71..cd447d7c5a5 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -19,918 +19,42 @@ #ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H #define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace grpc { - -namespace internal { -/// Common interface for all synchronous client side streaming. -class ClientStreamingInterface { - public: - virtual ~ClientStreamingInterface() {} - - /// Block waiting until the stream finishes and a final status of the call is - /// available. - /// - /// It is appropriate to call this method when both: - /// * the calling code (client-side) has no more message to send - /// (this can be declared implicitly by calling this method, or - /// explicitly through an earlier call to WritesDone method of the - /// class in use, e.g. \a ClientWriterInterface::WritesDone or - /// \a ClientReaderWriterInterface::WritesDone). - /// * there are no more messages to be received from the server (which can - /// be known implicitly, or explicitly from an earlier call to \a - /// ReaderInterface::Read that returned "false"). - /// - /// This function will return either: - /// - when all incoming messages have been read and the server has - /// returned status. - /// - when the server has returned a non-OK status. - /// - OR when the call failed for some reason and the library generated a - /// status. - /// - /// Return values: - /// - \a Status contains the status code, message and details for the call - /// - the \a ClientContext associated with this call is updated with - /// possible trailing metadata sent from the server. - virtual Status Finish() = 0; -}; - -/// Common interface for all synchronous server side streaming. -class ServerStreamingInterface { - public: - virtual ~ServerStreamingInterface() {} - - /// Block to send initial metadata to client. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// The initial metadata that will be sent to the client will be - /// taken from the \a ServerContext associated with the call. - virtual void SendInitialMetadata() = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. template -class ReaderInterface { - public: - virtual ~ReaderInterface() {} - - /// Get an upper bound on the next message size available for reading on this - /// stream. - virtual bool NextMessageSize(uint32_t* sz) = 0; - - /// Block to read a message and parse to \a msg. Returns \a true on success. - /// This is thread-safe with respect to \a Write or \WritesDone methods on - /// the same stream. It should not be called concurrently with another \a - /// Read on the same stream as the order of delivery will not be defined. - /// - /// \param[out] msg The read message. - /// - /// \return \a false when there will be no more incoming messages, either - /// because the other side has called \a WritesDone() or the stream has failed - /// (or been cancelled). - virtual bool Read(R* msg) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class WriterInterface { - public: - virtual ~WriterInterface() {} - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - virtual bool Write(const W& msg, WriteOptions options) = 0; - - /// Block to write \a msg to the stream with default write options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// - /// \return \a true on success, \a false when the stream has been closed. - inline bool Write(const W& msg) { return Write(msg, WriteOptions()); } - - /// Write \a msg and coalesce it with the writing of trailing metadata, using - /// WriteOptions \a options. - /// - /// For client, WriteLast is equivalent of performing Write and WritesDone in - /// a single step. \a msg and trailing metadata are coalesced and sent on wire - /// by calling this function. For server, WriteLast buffers the \a msg. - /// The writing of \a msg is held until the service handler returns, - /// where \a msg and trailing metadata are coalesced and sent on wire. - /// Note that WriteLast can only buffer \a msg up to the flow control window - /// size. If \a msg size is larger than the window size, it will be sent on - /// wire without buffering. - /// - /// \param[in] msg The message to be written to the stream. - /// \param[in] options The WriteOptions to be used to write this message. - void WriteLast(const W& msg, WriteOptions options) { - Write(msg, options.set_last_message()); - } -}; - -} // namespace internal +using ClientReaderInterface = ::grpc_impl::ClientReaderInterface; -/// Client-side interface for streaming reads of message of type \a R. template -class ClientReaderInterface : public internal::ClientStreamingInterface, - public internal::ReaderInterface { - public: - /// Block to wait for initial metadata from server. The received metadata - /// can only be accessed after this call returns. Should only be called before - /// the first read. Calling this method is optional, and if it is not called - /// the metadata will be available in ClientContext after the first read. - virtual void WaitForInitialMetadata() = 0; -}; - -namespace internal { -template -class ClientReaderFactory { - public: - template - static ClientReader* Create(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - const W& request) { - return new ClientReader(channel, method, context, request); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for doing server-streaming RPCs, -/// where the stream of messages coming from the server has messages -/// of type \a R. -template -class ClientReader final : public ClientReaderInterface { - public: - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for - /// semantics. - /// - // Side effect: - /// Once complete, the initial metadata read from - /// the server will be accessible through the \a ClientContext used to - /// construct this object. - void WaitForInitialMetadata() override { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); /// status ignored - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_.max_receive_message_size(); - return true; - } - - /// See the \a ReaderInterface.Read method for semantics. - /// Side effect: - /// This also receives initial metadata from the server, if not - /// already received (if initial metadata is received, it can be then - /// accessed through the \a ClientContext associated with this call). - bool Read(R* msg) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - ops.RecvMessage(msg); - call_.PerformOps(&ops); - return cq_.Pluck(&ops) && ops.got_message; - } - - /// See the \a ClientStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// The \a ClientContext associated with this call is updated with - /// possible metadata received from the server. - Status Finish() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops; - Status status; - ops.ClientRecvStatus(context_, &status); - call_.PerformOps(&ops); - GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); - return status; - } - - private: - friend class internal::ClientReaderFactory; - ::grpc_impl::ClientContext* context_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; - - /// Block to create a stream and write the initial metadata and \a request - /// out. Note that \a context will be used to fill in custom initial - /// metadata used to send to the server when starting the call. - template - ClientReader(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, const W& request) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); - ops.ClientSendClose(); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } -}; - -/// Client-side interface for streaming writes of message type \a W. +using ClientReader = ::grpc_impl::ClientReader; template -class ClientWriterInterface : public internal::ClientStreamingInterface, - public internal::WriterInterface { - public: - /// Half close writing from the client. (signal that the stream of messages - /// coming from the client is complete). - /// Blocks until currently-pending writes are completed. - /// Thread safe with respect to \a ReaderInterface::Read operations only - /// - /// \return Whether the writes were successful. - virtual bool WritesDone() = 0; -}; - -namespace internal { +using ClientWriterInterface = ::grpc_impl::ClientWriterInterface; template -class ClientWriterFactory { - public: - template - static ClientWriter* Create(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, - R* response) { - return new ClientWriter(channel, method, context, response); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for doing client-streaming RPCs, -/// where the outgoing message stream coming from the client has messages of -/// type \a W. -template -class ClientWriter : public ClientWriterInterface { - public: - /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for - /// semantics. - /// - // Side effect: - /// Once complete, the initial metadata read from the server will be - /// accessible through the \a ClientContext used to construct this object. - void WaitForInitialMetadata() { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); // status ignored - } - - /// See the WriterInterface.Write(const W& msg, WriteOptions options) method - /// for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call). - using ::grpc::internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - - if (options.is_last_message()) { - options.set_buffer_hint(); - ops.ClientSendClose(); - } - if (context_->initial_metadata_corked_) { - ops.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - context_->set_initial_metadata_corked(false); - } - if (!ops.SendMessagePtr(&msg, options).ok()) { - return false; - } - - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - bool WritesDone() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; - ops.ClientSendClose(); - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - /// See the ClientStreamingInterface.Finish method for semantics. - /// Side effects: - /// - Also receives initial metadata if not already received. - /// - Attempts to fill in the \a response parameter passed - /// to the constructor of this instance with the response - /// message from the server. - Status Finish() override { - Status status; - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, &status); - call_.PerformOps(&finish_ops_); - GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_)); - return status; - } - - private: - friend class internal::ClientWriterFactory; - - /// Block to create a stream (i.e. send request headers and other initial - /// metadata to the server). Note that \a context will be used to fill - /// in custom initial metadata. \a response will be filled in with the - /// single expected response message from the server upon a successful - /// call to the \a Finish method of this instance. - template - ClientWriter(ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context, R* response) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - finish_ops_.RecvMessage(response); - finish_ops_.AllowNoMessage(); - - if (!context_->initial_metadata_corked_) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } - } - - ::grpc_impl::ClientContext* context_; - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpGenericRecvMessage, - ::grpc::internal::CallOpClientRecvStatus> - finish_ops_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; -}; - -/// Client-side interface for bi-directional streaming with -/// client-to-server stream messages of type \a W and -/// server-to-client stream messages of type \a R. -template -class ClientReaderWriterInterface : public internal::ClientStreamingInterface, - public internal::WriterInterface, - public internal::ReaderInterface { - public: - /// Block to wait for initial metadata from server. The received metadata - /// can only be accessed after this call returns. Should only be called before - /// the first read. Calling this method is optional, and if it is not called - /// the metadata will be available in ClientContext after the first read. - virtual void WaitForInitialMetadata() = 0; - - /// Half close writing from the client. (signal that the stream of messages - /// coming from the clinet is complete). - /// Blocks until currently-pending writes are completed. - /// Thread-safe with respect to \a ReaderInterface::Read - /// - /// \return Whether the writes were successful. - virtual bool WritesDone() = 0; -}; - -namespace internal { +using ClientWriter = ::grpc_impl::ClientWriter; template -class ClientReaderWriterFactory { - public: - static ClientReaderWriter* Create( - ::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context) { - return new ClientReaderWriter(channel, method, context); - } -}; -} // namespace internal - -/// Synchronous (blocking) client-side API for bi-directional streaming RPCs, -/// where the outgoing message stream coming from the client has messages of -/// type \a W, and the incoming messages stream coming from the server has -/// messages of type \a R. +using ClientReaderWriterInterface = + ::grpc_impl::ClientReaderWriterInterface; template -class ClientReaderWriter final : public ClientReaderWriterInterface { - public: - /// Block waiting to read initial metadata from the server. - /// This call is optional, but if it is used, it cannot be used concurrently - /// with or after the \a Finish method. - /// - /// Once complete, the initial metadata read from the server will be - /// accessible through the \a ClientContext used to construct this object. - void WaitForInitialMetadata() override { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> - ops; - ops.RecvInitialMetadata(context_); - call_.PerformOps(&ops); - cq_.Pluck(&ops); // status ignored - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_.max_receive_message_size(); - return true; - } - - /// See the \a ReaderInterface.Read method for semantics. - /// Side effect: - /// Also receives initial metadata if not already received (updates the \a - /// ClientContext associated with this call in that case). - bool Read(R* msg) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpRecvMessage> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - ops.RecvMessage(msg); - call_.PerformOps(&ops); - return cq_.Pluck(&ops) && ops.got_message; - } - - /// See the \a WriterInterface.Write method for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call to fill in values). - using ::grpc::internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, - ::grpc::internal::CallOpSendMessage, - ::grpc::internal::CallOpClientSendClose> - ops; - - if (options.is_last_message()) { - options.set_buffer_hint(); - ops.ClientSendClose(); - } - if (context_->initial_metadata_corked_) { - ops.SendInitialMetadata(&context_->send_initial_metadata_, - context_->initial_metadata_flags()); - context_->set_initial_metadata_corked(false); - } - if (!ops.SendMessagePtr(&msg, options).ok()) { - return false; - } - - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - bool WritesDone() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; - ops.ClientSendClose(); - call_.PerformOps(&ops); - return cq_.Pluck(&ops); - } - - /// See the ClientStreamingInterface.Finish method for semantics. - /// - /// Side effect: - /// - the \a ClientContext associated with this call is updated with - /// possible trailing metadata sent from the server. - Status Finish() override { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, - ::grpc::internal::CallOpClientRecvStatus> - ops; - if (!context_->initial_metadata_received_) { - ops.RecvInitialMetadata(context_); - } - Status status; - ops.ClientRecvStatus(context_, &status); - call_.PerformOps(&ops); - GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); - return status; - } - - private: - friend class internal::ClientReaderWriterFactory; - - ::grpc_impl::ClientContext* context_; - ::grpc_impl::CompletionQueue cq_; - ::grpc::internal::Call call_; - - /// Block to create a stream and write the initial metadata and \a request - /// out. Note that \a context will be used to fill in custom initial metadata - /// used to send to the server when starting the call. - ClientReaderWriter(::grpc::ChannelInterface* channel, - const ::grpc::internal::RpcMethod& method, - ::grpc_impl::ClientContext* context) - : context_(context), - cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, - nullptr}), // Pluckable cq - call_(channel->CreateCall(method, context, &cq_)) { - if (!context_->initial_metadata_corked_) { - ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> - ops; - ops.SendInitialMetadata(&context->send_initial_metadata_, - context->initial_metadata_flags()); - call_.PerformOps(&ops); - cq_.Pluck(&ops); - } - } -}; - -/// Server-side interface for streaming reads of message of type \a R. +using ClientReaderWriter = ::grpc_impl::ClientReaderWriter; template -class ServerReaderInterface : public internal::ServerStreamingInterface, - public internal::ReaderInterface {}; - -/// Synchronous (blocking) server-side API for doing client-streaming RPCs, -/// where the incoming message stream coming from the client has messages of -/// type \a R. +using ServerReaderInterface = ::grpc_impl::ServerReaderInterface; template -class ServerReader final : public ServerReaderInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - internal::CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - bool NextMessageSize(uint32_t* sz) override { - *sz = call_->max_receive_message_size(); - return true; - } - - bool Read(R* msg) override { - internal::CallOpSet> ops; - ops.RecvMessage(msg); - call_->PerformOps(&ops); - return call_->cq()->Pluck(&ops) && ops.got_message; - } - - private: - internal::Call* const call_; - ::grpc_impl::ServerContext* const ctx_; - - template - friend class internal::ClientStreamingHandler; - - ServerReader(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} -}; - -/// Server-side interface for streaming writes of message of type \a W. +using ServerReader = ::grpc_impl::ServerReader; template -class ServerWriterInterface : public internal::ServerStreamingInterface, - public internal::WriterInterface {}; - -/// Synchronous (blocking) server-side API for doing for doing a -/// server-streaming RPCs, where the outgoing message stream coming from the -/// server has messages of type \a W. +using ServerWriterInterface = ::grpc_impl::ServerWriterInterface; template -class ServerWriter final : public ServerWriterInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. - /// Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - internal::CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - /// See the \a WriterInterface.Write method for semantics. - /// - /// Side effect: - /// Also sends initial metadata if not already sent (using the - /// \a ClientContext associated with this call to fill in values). - using internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - if (options.is_last_message()) { - options.set_buffer_hint(); - } - - if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { - return false; - } - if (!ctx_->sent_initial_metadata_) { - ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - call_->PerformOps(&ctx_->pending_ops_); - // if this is the last message we defer the pluck until AFTER we start - // the trailing md op. This prevents hangs. See - // https://github.com/grpc/grpc/issues/11546 - if (options.is_last_message()) { - ctx_->has_pending_ops_ = true; - return true; - } - ctx_->has_pending_ops_ = false; - return call_->cq()->Pluck(&ctx_->pending_ops_); - } - - private: - internal::Call* const call_; - ::grpc_impl::ServerContext* const ctx_; - - template - friend class internal::ServerStreamingHandler; - - ServerWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} -}; - -/// Server-side interface for bi-directional streaming. +using ServerWriter = ::grpc_impl::ServerWriter; template -class ServerReaderWriterInterface : public internal::ServerStreamingInterface, - public internal::WriterInterface, - public internal::ReaderInterface {}; - -/// Actual implementation of bi-directional streaming -namespace internal { -template -class ServerReaderWriterBody final { - public: - ServerReaderWriterBody(Call* call, ::grpc_impl::ServerContext* ctx) - : call_(call), ctx_(ctx) {} - - void SendInitialMetadata() { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - CallOpSet ops; - ops.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ops.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - call_->PerformOps(&ops); - call_->cq()->Pluck(&ops); - } - - bool NextMessageSize(uint32_t* sz) { - *sz = call_->max_receive_message_size(); - return true; - } - - bool Read(R* msg) { - CallOpSet> ops; - ops.RecvMessage(msg); - call_->PerformOps(&ops); - return call_->cq()->Pluck(&ops) && ops.got_message; - } - - bool Write(const W& msg, WriteOptions options) { - if (options.is_last_message()) { - options.set_buffer_hint(); - } - if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { - return false; - } - if (!ctx_->sent_initial_metadata_) { - ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, - ctx_->initial_metadata_flags()); - if (ctx_->compression_level_set()) { - ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); - } - ctx_->sent_initial_metadata_ = true; - } - call_->PerformOps(&ctx_->pending_ops_); - // if this is the last message we defer the pluck until AFTER we start - // the trailing md op. This prevents hangs. See - // https://github.com/grpc/grpc/issues/11546 - if (options.is_last_message()) { - ctx_->has_pending_ops_ = true; - return true; - } - ctx_->has_pending_ops_ = false; - return call_->cq()->Pluck(&ctx_->pending_ops_); - } - - private: - Call* const call_; - ::grpc_impl::ServerContext* const ctx_; -}; - -} // namespace internal - -/// Synchronous (blocking) server-side API for a bidirectional -/// streaming call, where the incoming message stream coming from the client has -/// messages of type \a R, and the outgoing message streaming coming from -/// the server has messages of type \a W. +using ServerReaderWriterInterface = + ::grpc_impl::ServerReaderWriterInterface; template -class ServerReaderWriter final : public ServerReaderWriterInterface { - public: - /// See the \a ServerStreamingInterface.SendInitialMetadata method - /// for semantics. Note that initial metadata will be affected by the - /// \a ServerContext associated with this call. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - bool Read(R* msg) override { return body_.Read(msg); } - - /// See the \a WriterInterface.Write(const W& msg, WriteOptions options) - /// method for semantics. - /// Side effect: - /// Also sends initial metadata if not already sent (using the \a - /// ServerContext associated with this call). - using internal::WriterInterface::Write; - bool Write(const W& msg, WriteOptions options) override { - return body_.Write(msg, options); - } - - private: - internal::ServerReaderWriterBody body_; - - friend class internal::TemplatedBidiStreamingHandler, - false>; - ServerReaderWriter(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx) {} -}; - -/// A class to represent a flow-controlled unary call. This is something -/// of a hybrid between conventional unary and streaming. This is invoked -/// through a unary call on the client side, but the server responds to it -/// as though it were a single-ping-pong streaming call. The server can use -/// the \a NextMessageSize method to determine an upper-bound on the size of -/// the message. A key difference relative to streaming: ServerUnaryStreamer -/// must have exactly 1 Read and exactly 1 Write, in that order, to function -/// correctly. Otherwise, the RPC is in error. +using ServerReaderWriter = ::grpc_impl::ServerReaderWriter; template -class ServerUnaryStreamer final - : public ServerReaderWriterInterface { - public: - /// Block to send initial metadata to client. - /// Implicit input parameter: - /// - the \a ServerContext associated with this call will be used for - /// sending initial metadata. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - /// Get an upper bound on the request message size from the client. - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a ReaderInterface::Read on the same stream since reads on - /// the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - bool Read(RequestType* request) override { - if (read_done_) { - return false; - } - read_done_ = true; - return body_.Read(request); - } - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - using internal::WriterInterface::Write; - bool Write(const ResponseType& response, WriteOptions options) override { - if (write_done_ || !read_done_) { - return false; - } - write_done_ = true; - return body_.Write(response, options); - } - - private: - internal::ServerReaderWriterBody body_; - bool read_done_; - bool write_done_; - - friend class internal::TemplatedBidiStreamingHandler< - ServerUnaryStreamer, true>; - ServerUnaryStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx), read_done_(false), write_done_(false) {} -}; - -/// A class to represent a flow-controlled server-side streaming call. -/// This is something of a hybrid between server-side and bidi streaming. -/// This is invoked through a server-side streaming call on the client side, -/// but the server responds to it as though it were a bidi streaming call that -/// must first have exactly 1 Read and then any number of Writes. +using ServerUnaryStreamer = + ::grpc_impl::ServerUnaryStreamer; template -class ServerSplitStreamer final - : public ServerReaderWriterInterface { - public: - /// Block to send initial metadata to client. - /// Implicit input parameter: - /// - the \a ServerContext associated with this call will be used for - /// sending initial metadata. - void SendInitialMetadata() override { body_.SendInitialMetadata(); } - - /// Get an upper bound on the request message size from the client. - bool NextMessageSize(uint32_t* sz) override { - return body_.NextMessageSize(sz); - } - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// This is thread-safe with respect to \a Write or \a WritesDone methods. It - /// should not be called concurrently with other streaming APIs - /// on the same stream. It is not meaningful to call it concurrently - /// with another \a ReaderInterface::Read on the same stream since reads on - /// the same stream are delivered in order. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - bool Read(RequestType* request) override { - if (read_done_) { - return false; - } - read_done_ = true; - return body_.Read(request); - } - - /// Block to write \a msg to the stream with WriteOptions \a options. - /// This is thread-safe with respect to \a ReaderInterface::Read - /// - /// \param msg The message to be written to the stream. - /// \param options The WriteOptions affecting the write operation. - /// - /// \return \a true on success, \a false when the stream has been closed. - using internal::WriterInterface::Write; - bool Write(const ResponseType& response, WriteOptions options) override { - return read_done_ && body_.Write(response, options); - } - - private: - internal::ServerReaderWriterBody body_; - bool read_done_; - - friend class internal::TemplatedBidiStreamingHandler< - ServerSplitStreamer, false>; - ServerSplitStreamer(internal::Call* call, ::grpc_impl::ServerContext* ctx) - : body_(call, ctx), read_done_(false) {} -}; +using ServerSplitStreamer = + ::grpc_impl::ServerSplitStreamer; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/sync_stream_impl.h b/include/grpcpp/impl/codegen/sync_stream_impl.h new file mode 100644 index 00000000000..dc764e0e27b --- /dev/null +++ b/include/grpcpp/impl/codegen/sync_stream_impl.h @@ -0,0 +1,944 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H +#define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc_impl { + +namespace internal { +/// Common interface for all synchronous client side streaming. +class ClientStreamingInterface { + public: + virtual ~ClientStreamingInterface() {} + + /// Block waiting until the stream finishes and a final status of the call is + /// available. + /// + /// It is appropriate to call this method when both: + /// * the calling code (client-side) has no more message to send + /// (this can be declared implicitly by calling this method, or + /// explicitly through an earlier call to WritesDone method of the + /// class in use, e.g. \a ClientWriterInterface::WritesDone or + /// \a ClientReaderWriterInterface::WritesDone). + /// * there are no more messages to be received from the server (which can + /// be known implicitly, or explicitly from an earlier call to \a + /// ReaderInterface::Read that returned "false"). + /// + /// This function will return either: + /// - when all incoming messages have been read and the server has + /// returned status. + /// - when the server has returned a non-OK status. + /// - OR when the call failed for some reason and the library generated a + /// status. + /// + /// Return values: + /// - \a Status contains the status code, message and details for the call + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. + virtual ::grpc::Status Finish() = 0; +}; + +/// Common interface for all synchronous server side streaming. +class ServerStreamingInterface { + public: + virtual ~ServerStreamingInterface() {} + + /// Block to send initial metadata to client. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// The initial metadata that will be sent to the client will be + /// taken from the \a ServerContext associated with the call. + virtual void SendInitialMetadata() = 0; +}; + +/// An interface that yields a sequence of messages of type \a R. +template +class ReaderInterface { + public: + virtual ~ReaderInterface() {} + + /// Get an upper bound on the next message size available for reading on this + /// stream. + virtual bool NextMessageSize(uint32_t* sz) = 0; + + /// Block to read a message and parse to \a msg. Returns \a true on success. + /// This is thread-safe with respect to \a Write or \WritesDone methods on + /// the same stream. It should not be called concurrently with another \a + /// Read on the same stream as the order of delivery will not be defined. + /// + /// \param[out] msg The read message. + /// + /// \return \a false when there will be no more incoming messages, either + /// because the other side has called \a WritesDone() or the stream has failed + /// (or been cancelled). + virtual bool Read(R* msg) = 0; +}; + +/// An interface that can be fed a sequence of messages of type \a W. +template +class WriterInterface { + public: + virtual ~WriterInterface() {} + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + virtual bool Write(const W& msg, ::grpc::WriteOptions options) = 0; + + /// Block to write \a msg to the stream with default write options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// + /// \return \a true on success, \a false when the stream has been closed. + inline bool Write(const W& msg) { return Write(msg, ::grpc::WriteOptions()); } + + /// Write \a msg and coalesce it with the writing of trailing metadata, using + /// WriteOptions \a options. + /// + /// For client, WriteLast is equivalent of performing Write and WritesDone in + /// a single step. \a msg and trailing metadata are coalesced and sent on wire + /// by calling this function. For server, WriteLast buffers the \a msg. + /// The writing of \a msg is held until the service handler returns, + /// where \a msg and trailing metadata are coalesced and sent on wire. + /// Note that WriteLast can only buffer \a msg up to the flow control window + /// size. If \a msg size is larger than the window size, it will be sent on + /// wire without buffering. + /// + /// \param[in] msg The message to be written to the stream. + /// \param[in] options The WriteOptions to be used to write this message. + void WriteLast(const W& msg, ::grpc::WriteOptions options) { + Write(msg, options.set_last_message()); + } +}; + +} // namespace internal + +/// Client-side interface for streaming reads of message of type \a R. +template +class ClientReaderInterface : public internal::ClientStreamingInterface, + public internal::ReaderInterface { + public: + /// Block to wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. + virtual void WaitForInitialMetadata() = 0; +}; + +namespace internal { +template +class ClientReaderFactory { + public: + template + static ClientReader* Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + const W& request) { + return new ClientReader(channel, method, context, request); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for doing server-streaming RPCs, +/// where the stream of messages coming from the server has messages +/// of type \a R. +template +class ClientReader final : public ClientReaderInterface { + public: + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from + /// the server will be accessible through the \a ClientContext used to + /// construct this object. + void WaitForInitialMetadata() override { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); /// status ignored + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_.max_receive_message_size(); + return true; + } + + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// This also receives initial metadata from the server, if not + /// already received (if initial metadata is received, it can be then + /// accessed through the \a ClientContext associated with this call). + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ops.RecvMessage(msg); + call_.PerformOps(&ops); + return cq_.Pluck(&ops) && ops.got_message; + } + + /// See the \a ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// The \a ClientContext associated with this call is updated with + /// possible metadata received from the server. + ::grpc::Status Finish() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops; + ::grpc::Status status; + ops.ClientRecvStatus(context_, &status); + call_.PerformOps(&ops); + GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); + return status; + } + + private: + friend class internal::ClientReaderFactory; + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; + + /// Block to create a stream and write the initial metadata and \a request + /// out. Note that \a context will be used to fill in custom initial + /// metadata used to send to the server when starting the call. + template + ClientReader(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, const W& request) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + // TODO(ctiller): don't assert + GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok()); + ops.ClientSendClose(); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } +}; + +/// Client-side interface for streaming writes of message type \a W. +template +class ClientWriterInterface : public internal::ClientStreamingInterface, + public internal::WriterInterface { + public: + /// Half close writing from the client. (signal that the stream of messages + /// coming from the client is complete). + /// Blocks until currently-pending writes are completed. + /// Thread safe with respect to \a ReaderInterface::Read operations only + /// + /// \return Whether the writes were successful. + virtual bool WritesDone() = 0; +}; + +namespace internal { +template +class ClientWriterFactory { + public: + template + static ClientWriter* Create(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, + R* response) { + return new ClientWriter(channel, method, context, response); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for doing client-streaming RPCs, +/// where the outgoing message stream coming from the client has messages of +/// type \a W. +template +class ClientWriter : public ClientWriterInterface { + public: + /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for + /// semantics. + /// + // Side effect: + /// Once complete, the initial metadata read from the server will be + /// accessible through the \a ClientContext used to construct this object. + void WaitForInitialMetadata() { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); // status ignored + } + + /// See the WriterInterface.Write(const W& msg, WriteOptions options) method + /// for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + + if (options.is_last_message()) { + options.set_buffer_hint(); + ops.ClientSendClose(); + } + if (context_->initial_metadata_corked_) { + ops.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + context_->set_initial_metadata_corked(false); + } + if (!ops.SendMessagePtr(&msg, options).ok()) { + return false; + } + + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + bool WritesDone() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; + ops.ClientSendClose(); + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + /// See the ClientStreamingInterface.Finish method for semantics. + /// Side effects: + /// - Also receives initial metadata if not already received. + /// - Attempts to fill in the \a response parameter passed + /// to the constructor of this instance with the response + /// message from the server. + ::grpc::Status Finish() override { + ::grpc::Status status; + if (!context_->initial_metadata_received_) { + finish_ops_.RecvInitialMetadata(context_); + } + finish_ops_.ClientRecvStatus(context_, &status); + call_.PerformOps(&finish_ops_); + GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_)); + return status; + } + + private: + friend class internal::ClientWriterFactory; + + /// Block to create a stream (i.e. send request headers and other initial + /// metadata to the server). Note that \a context will be used to fill + /// in custom initial metadata. \a response will be filled in with the + /// single expected response message from the server upon a successful + /// call to the \a Finish method of this instance. + template + ClientWriter(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context, R* response) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + finish_ops_.RecvMessage(response); + finish_ops_.AllowNoMessage(); + + if (!context_->initial_metadata_corked_) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } + } + + ::grpc_impl::ClientContext* context_; + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpGenericRecvMessage, + ::grpc::internal::CallOpClientRecvStatus> + finish_ops_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; +}; + +/// Client-side interface for bi-directional streaming with +/// client-to-server stream messages of type \a W and +/// server-to-client stream messages of type \a R. +template +class ClientReaderWriterInterface : public internal::ClientStreamingInterface, + public internal::WriterInterface, + public internal::ReaderInterface { + public: + /// Block to wait for initial metadata from server. The received metadata + /// can only be accessed after this call returns. Should only be called before + /// the first read. Calling this method is optional, and if it is not called + /// the metadata will be available in ClientContext after the first read. + virtual void WaitForInitialMetadata() = 0; + + /// Half close writing from the client. (signal that the stream of messages + /// coming from the clinet is complete). + /// Blocks until currently-pending writes are completed. + /// Thread-safe with respect to \a ReaderInterface::Read + /// + /// \return Whether the writes were successful. + virtual bool WritesDone() = 0; +}; + +namespace internal { +template +class ClientReaderWriterFactory { + public: + static ClientReaderWriter* Create( + ::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) { + return new ClientReaderWriter(channel, method, context); + } +}; +} // namespace internal + +/// Synchronous (blocking) client-side API for bi-directional streaming RPCs, +/// where the outgoing message stream coming from the client has messages of +/// type \a W, and the incoming messages stream coming from the server has +/// messages of type \a R. +template +class ClientReaderWriter final : public ClientReaderWriterInterface { + public: + /// Block waiting to read initial metadata from the server. + /// This call is optional, but if it is used, it cannot be used concurrently + /// with or after the \a Finish method. + /// + /// Once complete, the initial metadata read from the server will be + /// accessible through the \a ClientContext used to construct this object. + void WaitForInitialMetadata() override { + GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata> + ops; + ops.RecvInitialMetadata(context_); + call_.PerformOps(&ops); + cq_.Pluck(&ops); // status ignored + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_.max_receive_message_size(); + return true; + } + + /// See the \a ReaderInterface.Read method for semantics. + /// Side effect: + /// Also receives initial metadata if not already received (updates the \a + /// ClientContext associated with this call in that case). + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpRecvMessage> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ops.RecvMessage(msg); + call_.PerformOps(&ops); + return cq_.Pluck(&ops) && ops.got_message; + } + + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, + ::grpc::internal::CallOpSendMessage, + ::grpc::internal::CallOpClientSendClose> + ops; + + if (options.is_last_message()) { + options.set_buffer_hint(); + ops.ClientSendClose(); + } + if (context_->initial_metadata_corked_) { + ops.SendInitialMetadata(&context_->send_initial_metadata_, + context_->initial_metadata_flags()); + context_->set_initial_metadata_corked(false); + } + if (!ops.SendMessagePtr(&msg, options).ok()) { + return false; + } + + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + bool WritesDone() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops; + ops.ClientSendClose(); + call_.PerformOps(&ops); + return cq_.Pluck(&ops); + } + + /// See the ClientStreamingInterface.Finish method for semantics. + /// + /// Side effect: + /// - the \a ClientContext associated with this call is updated with + /// possible trailing metadata sent from the server. + ::grpc::Status Finish() override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata, + ::grpc::internal::CallOpClientRecvStatus> + ops; + if (!context_->initial_metadata_received_) { + ops.RecvInitialMetadata(context_); + } + ::grpc::Status status; + ops.ClientRecvStatus(context_, &status); + call_.PerformOps(&ops); + GPR_CODEGEN_ASSERT(cq_.Pluck(&ops)); + return status; + } + + private: + friend class internal::ClientReaderWriterFactory; + + ::grpc_impl::ClientContext* context_; + ::grpc_impl::CompletionQueue cq_; + ::grpc::internal::Call call_; + + /// Block to create a stream and write the initial metadata and \a request + /// out. Note that \a context will be used to fill in custom initial metadata + /// used to send to the server when starting the call. + ClientReaderWriter(::grpc::ChannelInterface* channel, + const ::grpc::internal::RpcMethod& method, + ::grpc_impl::ClientContext* context) + : context_(context), + cq_(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq + call_(channel->CreateCall(method, context, &cq_)) { + if (!context_->initial_metadata_corked_) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&context->send_initial_metadata_, + context->initial_metadata_flags()); + call_.PerformOps(&ops); + cq_.Pluck(&ops); + } + } +}; + +/// Server-side interface for streaming reads of message of type \a R. +template +class ServerReaderInterface : public internal::ServerStreamingInterface, + public internal::ReaderInterface {}; + +/// Synchronous (blocking) server-side API for doing client-streaming RPCs, +/// where the incoming message stream coming from the client has messages of +/// type \a R. +template +class ServerReader final : public ServerReaderInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + bool NextMessageSize(uint32_t* sz) override { + *sz = call_->max_receive_message_size(); + return true; + } + + bool Read(R* msg) override { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> ops; + ops.RecvMessage(msg); + call_->PerformOps(&ops); + return call_->cq()->Pluck(&ops) && ops.got_message; + } + + private: + ::grpc::internal::Call* const call_; + ServerContext* const ctx_; + + template + friend class ::grpc::internal::ClientStreamingHandler; + + ServerReader(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} +}; + +/// Server-side interface for streaming writes of message of type \a W. +template +class ServerWriterInterface : public internal::ServerStreamingInterface, + public internal::WriterInterface {}; + +/// Synchronous (blocking) server-side API for doing for doing a +/// server-streaming RPCs, where the outgoing message stream coming from the +/// server has messages of type \a W. +template +class ServerWriter final : public ServerWriterInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. + /// Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> + ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + /// See the \a WriterInterface.Write method for semantics. + /// + /// Side effect: + /// Also sends initial metadata if not already sent (using the + /// \a ClientContext associated with this call to fill in values). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + if (options.is_last_message()) { + options.set_buffer_hint(); + } + + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { + return false; + } + if (!ctx_->sent_initial_metadata_) { + ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + call_->PerformOps(&ctx_->pending_ops_); + // if this is the last message we defer the pluck until AFTER we start + // the trailing md op. This prevents hangs. See + // https://github.com/grpc/grpc/issues/11546 + if (options.is_last_message()) { + ctx_->has_pending_ops_ = true; + return true; + } + ctx_->has_pending_ops_ = false; + return call_->cq()->Pluck(&ctx_->pending_ops_); + } + + private: + ::grpc::internal::Call* const call_; + ::grpc_impl::ServerContext* const ctx_; + + template + friend class ::grpc::internal::ServerStreamingHandler; + + ServerWriter(::grpc::internal::Call* call, ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} +}; + +/// Server-side interface for bi-directional streaming. +template +class ServerReaderWriterInterface : public internal::ServerStreamingInterface, + public internal::WriterInterface, + public internal::ReaderInterface {}; + +/// Actual implementation of bi-directional streaming +namespace internal { +template +class ServerReaderWriterBody final { + public: + ServerReaderWriterBody(grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : call_(call), ctx_(ctx) {} + + void SendInitialMetadata() { + GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); + + grpc::internal::CallOpSet ops; + ops.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + call_->PerformOps(&ops); + call_->cq()->Pluck(&ops); + } + + bool NextMessageSize(uint32_t* sz) { + *sz = call_->max_receive_message_size(); + return true; + } + + bool Read(R* msg) { + ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage> ops; + ops.RecvMessage(msg); + call_->PerformOps(&ops); + return call_->cq()->Pluck(&ops) && ops.got_message; + } + + bool Write(const W& msg, ::grpc::WriteOptions options) { + if (options.is_last_message()) { + options.set_buffer_hint(); + } + if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) { + return false; + } + if (!ctx_->sent_initial_metadata_) { + ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_, + ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ctx_->pending_ops_.set_compression_level(ctx_->compression_level()); + } + ctx_->sent_initial_metadata_ = true; + } + call_->PerformOps(&ctx_->pending_ops_); + // if this is the last message we defer the pluck until AFTER we start + // the trailing md op. This prevents hangs. See + // https://github.com/grpc/grpc/issues/11546 + if (options.is_last_message()) { + ctx_->has_pending_ops_ = true; + return true; + } + ctx_->has_pending_ops_ = false; + return call_->cq()->Pluck(&ctx_->pending_ops_); + } + + private: + grpc::internal::Call* const call_; + ::grpc_impl::ServerContext* const ctx_; +}; + +} // namespace internal + +/// Synchronous (blocking) server-side API for a bidirectional +/// streaming call, where the incoming message stream coming from the client has +/// messages of type \a R, and the outgoing message streaming coming from +/// the server has messages of type \a W. +template +class ServerReaderWriter final : public ServerReaderWriterInterface { + public: + /// See the \a ServerStreamingInterface.SendInitialMetadata method + /// for semantics. Note that initial metadata will be affected by the + /// \a ServerContext associated with this call. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + bool Read(R* msg) override { return body_.Read(msg); } + + /// See the \a WriterInterface.Write(const W& msg, WriteOptions options) + /// method for semantics. + /// Side effect: + /// Also sends initial metadata if not already sent (using the \a + /// ServerContext associated with this call). + using internal::WriterInterface::Write; + bool Write(const W& msg, ::grpc::WriteOptions options) override { + return body_.Write(msg, options); + } + + private: + internal::ServerReaderWriterBody body_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerReaderWriter, false>; + ServerReaderWriter(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx) {} +}; + +/// A class to represent a flow-controlled unary call. This is something +/// of a hybrid between conventional unary and streaming. This is invoked +/// through a unary call on the client side, but the server responds to it +/// as though it were a single-ping-pong streaming call. The server can use +/// the \a NextMessageSize method to determine an upper-bound on the size of +/// the message. A key difference relative to streaming: ServerUnaryStreamer +/// must have exactly 1 Read and exactly 1 Write, in that order, to function +/// correctly. Otherwise, the RPC is in error. +template +class ServerUnaryStreamer final + : public ServerReaderWriterInterface { + public: + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + /// Get an upper bound on the request message size from the client. + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a ReaderInterface::Read on the same stream since reads on + /// the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + bool Read(RequestType* request) override { + if (read_done_) { + return false; + } + read_done_ = true; + return body_.Read(request); + } + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + using internal::WriterInterface::Write; + bool Write(const ResponseType& response, + ::grpc::WriteOptions options) override { + if (write_done_ || !read_done_) { + return false; + } + write_done_ = true; + return body_.Write(response, options); + } + + private: + internal::ServerReaderWriterBody body_; + bool read_done_; + bool write_done_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerUnaryStreamer, true>; + ServerUnaryStreamer(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx), read_done_(false), write_done_(false) {} +}; + +/// A class to represent a flow-controlled server-side streaming call. +/// This is something of a hybrid between server-side and bidi streaming. +/// This is invoked through a server-side streaming call on the client side, +/// but the server responds to it as though it were a bidi streaming call that +/// must first have exactly 1 Read and then any number of Writes. +template +class ServerSplitStreamer final + : public ServerReaderWriterInterface { + public: + /// Block to send initial metadata to client. + /// Implicit input parameter: + /// - the \a ServerContext associated with this call will be used for + /// sending initial metadata. + void SendInitialMetadata() override { body_.SendInitialMetadata(); } + + /// Get an upper bound on the request message size from the client. + bool NextMessageSize(uint32_t* sz) override { + return body_.NextMessageSize(sz); + } + + /// Read a message of type \a R into \a msg. Completion will be notified by \a + /// tag on the associated completion queue. + /// This is thread-safe with respect to \a Write or \a WritesDone methods. It + /// should not be called concurrently with other streaming APIs + /// on the same stream. It is not meaningful to call it concurrently + /// with another \a ReaderInterface::Read on the same stream since reads on + /// the same stream are delivered in order. + /// + /// \param[out] msg Where to eventually store the read message. + /// \param[in] tag The tag identifying the operation. + bool Read(RequestType* request) override { + if (read_done_) { + return false; + } + read_done_ = true; + return body_.Read(request); + } + + /// Block to write \a msg to the stream with WriteOptions \a options. + /// This is thread-safe with respect to \a ReaderInterface::Read + /// + /// \param msg The message to be written to the stream. + /// \param options The WriteOptions affecting the write operation. + /// + /// \return \a true on success, \a false when the stream has been closed. + using internal::WriterInterface::Write; + bool Write(const ResponseType& response, + ::grpc::WriteOptions options) override { + return read_done_ && body_.Write(response, options); + } + + private: + internal::ServerReaderWriterBody body_; + bool read_done_; + + friend class ::grpc::internal::TemplatedBidiStreamingHandler< + ServerSplitStreamer, false>; + ServerSplitStreamer(::grpc::internal::Call* call, + ::grpc_impl::ServerContext* ctx) + : body_(call, ctx), read_done_(false) {} +}; + +} // namespace grpc_impl + +#endif // GRPCPP_IMPL_CODEGEN_SYNC_STREAM_IMPL_H diff --git a/include/grpcpp/support/async_stream_impl.h b/include/grpcpp/support/async_stream_impl.h new file mode 100644 index 00000000000..cff700d3fa9 --- /dev/null +++ b/include/grpcpp/support/async_stream_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H +#define GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_ASYNC_STREAM_IMPL_H diff --git a/include/grpcpp/support/async_unary_call_impl.h b/include/grpcpp/support/async_unary_call_impl.h new file mode 100644 index 00000000000..488fe87515a --- /dev/null +++ b/include/grpcpp/support/async_unary_call_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H +#define GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_ASYNC_UNARY_CALL_IMPL_H diff --git a/include/grpcpp/support/client_callback_impl.h b/include/grpcpp/support/client_callback_impl.h new file mode 100644 index 00000000000..ed8df412496 --- /dev/null +++ b/include/grpcpp/support/client_callback_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H +#define GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_CALLBACK_IMPL_H diff --git a/include/grpcpp/support/server_callback_impl.h b/include/grpcpp/support/server_callback_impl.h new file mode 100644 index 00000000000..a91c8141dd8 --- /dev/null +++ b/include/grpcpp/support/server_callback_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H +#define GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_SERVER_CALLBACK_IMPL_H diff --git a/include/grpcpp/support/sync_stream_impl.h b/include/grpcpp/support/sync_stream_impl.h new file mode 100644 index 00000000000..a00e425acfc --- /dev/null +++ b/include/grpcpp/support/sync_stream_impl.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H +#define GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H + +#include + +#endif // GRPCPP_SUPPORT_SYNC_STREAM_IMPL_H diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 358efe9fd79..044647d9a81 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -143,6 +143,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, "grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/client_callback.h", "grpcpp/impl/codegen/client_context.h", + "grpcpp/impl/codegen/completion_queue.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/proto_utils.h", "grpcpp/impl/codegen/rpc_method.h", @@ -946,11 +947,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerReadReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedReadReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerReadReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedReadReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, @@ -962,11 +964,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerWriteReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedWriteReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerWriteReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedWriteReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, @@ -978,11 +981,12 @@ void PrintHeaderServerCallbackMethodsHelper( " abort();\n" " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" "}\n"); - printer->Print(*vars, - "virtual ::grpc::experimental::ServerBidiReactor< " - "$RealRequest$, $RealResponse$>* $Method$() {\n" - " return new ::grpc::internal::UnimplementedBidiReactor<\n" - " $RealRequest$, $RealResponse$>;}\n"); + printer->Print( + *vars, + "virtual ::grpc::experimental::ServerBidiReactor< " + "$RealRequest$, $RealResponse$>* $Method$() {\n" + " return new ::grpc_impl::internal::UnimplementedBidiReactor<\n" + " $RealRequest$, $RealResponse$>;}\n"); } } @@ -1010,7 +1014,7 @@ void PrintHeaderServerMethodCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackUnaryHandler< " + " new ::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" @@ -1024,7 +1028,7 @@ void PrintHeaderServerMethodCallback( "void SetMessageAllocatorFor_$Method$(\n" " ::grpc::experimental::MessageAllocator< " "$RealRequest$, $RealResponse$>* allocator) {\n" - " static_cast<::grpc::internal::CallbackUnaryHandler< " + " static_cast<::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>*>(\n" " ::grpc::Service::experimental().GetHandler($Idx$))\n" " ->SetMessageAllocator(allocator);\n"); @@ -1032,21 +1036,21 @@ void PrintHeaderServerMethodCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackClientStreamingHandler< " + " new ::grpc_impl::internal::CallbackClientStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackServerStreamingHandler< " + " new ::grpc_impl::internal::CallbackServerStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n" - " new ::grpc::internal::CallbackBidiHandler< " + " new ::grpc_impl::internal::CallbackBidiHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } @@ -1084,7 +1088,7 @@ void PrintHeaderServerMethodRawCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackUnaryHandler< " + " new ::grpc_impl::internal::CallbackUnaryHandler< " "$RealRequest$, $RealResponse$>(\n" " [this](::grpc::ServerContext* context,\n" " const $RealRequest$* request,\n" @@ -1098,21 +1102,21 @@ void PrintHeaderServerMethodRawCallback( printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackClientStreamingHandler< " + " new ::grpc_impl::internal::CallbackClientStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackServerStreamingHandler< " + " new ::grpc_impl::internal::CallbackServerStreamingHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } else if (method->BidiStreaming()) { printer->Print( *vars, " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n" - " new ::grpc::internal::CallbackBidiHandler< " + " new ::grpc_impl::internal::CallbackBidiHandler< " "$RealRequest$, $RealResponse$>(\n" " [this] { return this->$Method$(); }));\n"); } @@ -1705,7 +1709,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " ::grpc::internal::CallbackUnaryCall" + " ::grpc_impl::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); @@ -1715,7 +1719,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const ::grpc::ByteBuffer* request, $Response$* response, " "std::function f) {\n"); printer->Print(*vars, - " ::grpc::internal::CallbackUnaryCall" + " ::grpc_impl::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); @@ -1725,7 +1729,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const $Request$* request, $Response$* response, " "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackUnaryFactory::Create" + " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, reactor);\n}\n\n"); @@ -1735,7 +1739,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "const ::grpc::ByteBuffer* request, $Response$* response, " "::grpc::experimental::ClientUnaryReactor* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackUnaryFactory::Create" + " ::grpc_impl::internal::ClientCallbackUnaryFactory::Create" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, reactor);\n}\n\n"); @@ -1751,7 +1755,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, printer->Print( *vars, " return " - "::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>" + "::grpc_impl::internal::ClientAsyncResponseReaderFactory< $Response$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request, $AsyncStart$);\n" @@ -1762,13 +1766,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientWriter< $Request$>* " "$ns$$Service$::Stub::$Method$Raw(" "::grpc::ClientContext* context, $Response$* response) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientWriterFactory< $Request$>::Create(" - "channel_.get(), " - "rpcmethod_$Method$_, " - "context, response);\n" - "}\n\n"); + printer->Print(*vars, + " return ::grpc_impl::internal::ClientWriterFactory< " + "$Request$>::Create(" + "channel_.get(), " + "rpcmethod_$Method$_, " + "context, response);\n" + "}\n\n"); printer->Print( *vars, @@ -1777,7 +1781,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "$Response$* response, " "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackWriterFactory< " + " ::grpc_impl::internal::ClientCallbackWriterFactory< " "$Request$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1796,7 +1800,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print( *vars, - " return ::grpc::internal::ClientAsyncWriterFactory< $Request$>" + " return ::grpc_impl::internal::ClientAsyncWriterFactory< $Request$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, response, $AsyncStart$$AsyncCreateArgs$);\n" @@ -1808,13 +1812,13 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientReader< $Response$>* " "$ns$$Service$::Stub::$Method$Raw(" "::grpc::ClientContext* context, const $Request$& request) {\n"); - printer->Print( - *vars, - " return ::grpc::internal::ClientReaderFactory< $Response$>::Create(" - "channel_.get(), " - "rpcmethod_$Method$_, " - "context, request);\n" - "}\n\n"); + printer->Print(*vars, + " return ::grpc_impl::internal::ClientReaderFactory< " + "$Response$>::Create(" + "channel_.get(), " + "rpcmethod_$Method$_, " + "context, request);\n" + "}\n\n"); printer->Print( *vars, @@ -1823,7 +1827,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "$Request$* request, " "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n"); printer->Print(*vars, - " ::grpc::internal::ClientCallbackReaderFactory< " + " ::grpc_impl::internal::ClientCallbackReaderFactory< " "$Response$>::Create(" "stub_->channel_.get(), " "stub_->rpcmethod_$Method$_, " @@ -1843,7 +1847,8 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print( *vars, - " return ::grpc::internal::ClientAsyncReaderFactory< $Response$>" + " return ::grpc_impl::internal::ClientAsyncReaderFactory< " + "$Response$>" "::Create(channel_.get(), cq, " "rpcmethod_$Method$_, " "context, request, $AsyncStart$$AsyncCreateArgs$);\n" @@ -1855,7 +1860,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::ClientReaderWriter< $Request$, $Response$>* " "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n"); printer->Print(*vars, - " return ::grpc::internal::ClientReaderWriterFactory< " + " return ::grpc_impl::internal::ClientReaderWriterFactory< " "$Request$, $Response$>::Create(" "channel_.get(), " "rpcmethod_$Method$_, " @@ -1868,13 +1873,14 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "ClientContext* context, " "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* " "reactor) {\n"); - printer->Print(*vars, - " ::grpc::internal::ClientCallbackReaderWriterFactory< " - "$Request$,$Response$>::Create(" - "stub_->channel_.get(), " - "stub_->rpcmethod_$Method$_, " - "context, reactor);\n" - "}\n\n"); + printer->Print( + *vars, + " ::grpc_impl::internal::ClientCallbackReaderWriterFactory< " + "$Request$,$Response$>::Create(" + "stub_->channel_.get(), " + "stub_->rpcmethod_$Method$_, " + "context, reactor);\n" + "}\n\n"); for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; @@ -1888,7 +1894,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n"); printer->Print(*vars, " return " - "::grpc::internal::ClientAsyncReaderWriterFactory< " + "::grpc_impl::internal::ClientAsyncReaderWriterFactory< " "$Request$, $Response$>::Create(" "channel_.get(), cq, " "rpcmethod_$Method$_, " @@ -2279,7 +2285,8 @@ void PrintMockClientMethods(grpc_generator::Printer* printer, printer->Print( *vars, "MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, " - "::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*" + "::grpc::ClientAsyncReaderWriterInterface<$Request$, " + "$Response$>*" "(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq" "$AsyncMethodParams$));\n"); } diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 41631c794f2..e7d3df7a497 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -27,11 +27,10 @@ namespace grpc_impl { namespace { std::unique_ptr CallInternal( grpc::ChannelInterface* channel, grpc::ClientContext* context, - const grpc::string& method, grpc::CompletionQueue* cq, bool start, - void* tag) { + const grpc::string& method, CompletionQueue* cq, bool start, void* tag) { return std::unique_ptr( - grpc::internal::ClientAsyncReaderWriterFactory:: + internal::ClientAsyncReaderWriterFactory:: Create(channel, cq, grpc::internal::RpcMethod( method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING), @@ -43,14 +42,14 @@ std::unique_ptr CallInternal( // begin a call to a named method std::unique_ptr GenericStub::Call( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq, void* tag) { + CompletionQueue* cq, void* tag) { return CallInternal(channel_.get(), context, method, cq, true, tag); } // setup a call to a named method std::unique_ptr GenericStub::PrepareCall( grpc::ClientContext* context, const grpc::string& method, - grpc::CompletionQueue* cq) { + CompletionQueue* cq) { return CallInternal(channel_.get(), context, method, cq, false, nullptr); } @@ -59,21 +58,20 @@ std::unique_ptr GenericStub::PrepareUnaryCall(grpc::ClientContext* context, const grpc::string& method, const grpc::ByteBuffer& request, - grpc::CompletionQueue* cq) { + CompletionQueue* cq) { return std::unique_ptr( - grpc::internal::ClientAsyncResponseReaderFactory< - grpc::ByteBuffer>::Create(channel_.get(), cq, - grpc::internal::RpcMethod( - method.c_str(), - grpc::internal::RpcMethod::NORMAL_RPC), - context, request, false)); + internal::ClientAsyncResponseReaderFactory::Create( + channel_.get(), cq, + grpc::internal::RpcMethod(method.c_str(), + grpc::internal::RpcMethod::NORMAL_RPC), + context, request, false)); } void GenericStub::experimental_type::UnaryCall( grpc::ClientContext* context, const grpc::string& method, const grpc::ByteBuffer* request, grpc::ByteBuffer* response, std::function on_completion) { - grpc::internal::CallbackUnaryCall( + internal::CallbackUnaryCall( stub_->channel_.get(), grpc::internal::RpcMethod(method.c_str(), grpc::internal::RpcMethod::NORMAL_RPC), @@ -82,9 +80,9 @@ void GenericStub::experimental_type::UnaryCall( void GenericStub::experimental_type::PrepareBidiStreamingCall( grpc::ClientContext* context, const grpc::string& method, - grpc::experimental::ClientBidiReactor* + experimental::ClientBidiReactor* reactor) { - grpc::internal::ClientCallbackReaderWriterFactory< + internal::ClientCallbackReaderWriterFactory< grpc::ByteBuffer, grpc::ByteBuffer>::Create(stub_->channel_.get(), grpc::internal::RpcMethod( diff --git a/src/cpp/server/async_generic_service.cc b/src/cpp/server/async_generic_service.cc index 30613768295..556447a7f40 100644 --- a/src/cpp/server/async_generic_service.cc +++ b/src/cpp/server/async_generic_service.cc @@ -24,8 +24,8 @@ namespace grpc { void AsyncGenericService::RequestCall( GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, - CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, - void* tag) { + ::grpc_impl::CompletionQueue* call_cq, + ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) { server_->RequestAsyncGenericCall(ctx, reader_writer, call_cq, notification_cq, tag); } diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index 4b926efdfe8..14a54d53ee0 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 1ba9ae1c9dc..1d68c2bdaea 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -69,14 +69,14 @@ ServerBuilder::~ServerBuilder() { } } -std::unique_ptr ServerBuilder::AddCompletionQueue( +std::unique_ptr ServerBuilder::AddCompletionQueue( bool is_frequently_polled) { - grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( + ServerCompletionQueue* cq = new ServerCompletionQueue( GRPC_CQ_NEXT, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, nullptr); cqs_.push_back(cq); - return std::unique_ptr(cq); + return std::unique_ptr(cq); } ServerBuilder& ServerBuilder::RegisterService(grpc::Service* service) { @@ -266,10 +266,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // This is different from the completion queues added to the server via // ServerBuilder's AddCompletionQueue() method (those completion queues // are in 'cqs_' member variable of ServerBuilder object) - std::shared_ptr>> - sync_server_cqs( - std::make_shared< - std::vector>>()); + std::shared_ptr>> + sync_server_cqs(std::make_shared< + std::vector>>()); bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { @@ -298,7 +297,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // Create completion queues to listen to incoming rpc requests for (int i = 0; i < sync_server_settings_.num_cqs; i++) { sync_server_cqs->emplace_back( - new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + new ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); } } diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index ba834237ae9..1e27fad3988 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -45,8 +45,7 @@ class ServerContext::CompletionOp final public: // initial refs: one in the server context, one in the cq // must ref the call before calling constructor and after deleting this - CompletionOp(::grpc::internal::Call* call, - ::grpc::internal::ServerReactor* reactor) + CompletionOp(::grpc::internal::Call* call, internal::ServerReactor* reactor) : call_(*call), reactor_(reactor), has_tag_(false), @@ -152,7 +151,7 @@ class ServerContext::CompletionOp final } ::grpc::internal::Call call_; - ::grpc::internal::ServerReactor* const reactor_; + internal::ServerReactor* const reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; @@ -294,9 +293,9 @@ void ServerContext::Clear() { } } -void ServerContext::BeginCompletionOp( - ::grpc::internal::Call* call, std::function callback, - ::grpc::internal::ServerReactor* reactor) { +void ServerContext::BeginCompletionOp(::grpc::internal::Call* call, + std::function callback, + internal::ServerReactor* reactor) { GPR_ASSERT(!completion_op_); if (rpc_info_) { rpc_info_->Ref(); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 035955023b8..34fb5bfb53f 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -336,7 +337,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, @@ -346,7 +347,7 @@ class ServiceA final { } void SetMessageAllocatorFor_MethodA1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } @@ -367,7 +368,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA2() { ::grpc::Service::experimental().MarkMethodCallback(1, - new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA2(); })); } ~ExperimentalWithCallbackMethod_MethodA2() override { @@ -379,7 +380,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA2() { - return new ::grpc::internal::UnimplementedReadReactor< + return new ::grpc_impl::internal::UnimplementedReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; template @@ -389,7 +390,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA3() { ::grpc::Service::experimental().MarkMethodCallback(2, - new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA3(); })); } ~ExperimentalWithCallbackMethod_MethodA3() override { @@ -401,7 +402,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA3() { - return new ::grpc::internal::UnimplementedWriteReactor< + return new ::grpc_impl::internal::UnimplementedWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; template @@ -411,7 +412,7 @@ class ServiceA final { public: ExperimentalWithCallbackMethod_MethodA4() { ::grpc::Service::experimental().MarkMethodCallback(3, - new ::grpc::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this] { return this->MethodA4(); })); } ~ExperimentalWithCallbackMethod_MethodA4() override { @@ -423,7 +424,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4() { - return new ::grpc::internal::UnimplementedBidiReactor< + return new ::grpc_impl::internal::UnimplementedBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>;} }; typedef ExperimentalWithCallbackMethod_MethodA1 > > > ExperimentalCallbackService; @@ -582,7 +583,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, @@ -607,7 +608,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA2() { ::grpc::Service::experimental().MarkMethodRawCallback(1, - new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA2(); })); } ~ExperimentalWithRawCallbackMethod_MethodA2() override { @@ -619,7 +620,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA2() { - return new ::grpc::internal::UnimplementedReadReactor< + return new ::grpc_impl::internal::UnimplementedReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -629,7 +630,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA3() { ::grpc::Service::experimental().MarkMethodRawCallback(2, - new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA3(); })); } ~ExperimentalWithRawCallbackMethod_MethodA3() override { @@ -641,7 +642,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA3() { - return new ::grpc::internal::UnimplementedWriteReactor< + return new ::grpc_impl::internal::UnimplementedWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -651,7 +652,7 @@ class ServiceA final { public: ExperimentalWithRawCallbackMethod_MethodA4() { ::grpc::Service::experimental().MarkMethodRawCallback(3, - new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this] { return this->MethodA4(); })); } ~ExperimentalWithRawCallbackMethod_MethodA4() override { @@ -663,7 +664,7 @@ class ServiceA final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA4() { - return new ::grpc::internal::UnimplementedBidiReactor< + return new ::grpc_impl::internal::UnimplementedBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>;} }; template @@ -814,7 +815,7 @@ class ServiceB final { public: ExperimentalWithCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>( [this](::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, @@ -824,7 +825,7 @@ class ServiceB final { } void SetMessageAllocatorFor_MethodB1( ::grpc::experimental::MessageAllocator< ::grpc::testing::Request, ::grpc::testing::Response>* allocator) { - static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( + static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>*>( ::grpc::Service::experimental().GetHandler(0)) ->SetMessageAllocator(allocator); } @@ -883,7 +884,7 @@ class ServiceB final { public: ExperimentalWithRawCallbackMethod_MethodB1() { ::grpc::Service::experimental().MarkMethodRawCallback(0, - new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this](::grpc::ServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response, diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 501be844410..bdb36ae1a7b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -947,7 +947,9 @@ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ +include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ +include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -956,6 +958,7 @@ include/grpcpp/impl/codegen/call_op_set_interface.h \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ +include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -983,6 +986,7 @@ include/grpcpp/impl/codegen/rpc_service_method.h \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ +include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -995,6 +999,7 @@ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ +include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ include/grpcpp/impl/method_handler_impl.h \ @@ -1024,11 +1029,14 @@ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ +include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ +include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -1036,6 +1044,7 @@ include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -1043,6 +1052,7 @@ include/grpcpp/support/status_code_enum.h \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ +include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 69ff7eb6098..57d6ca8b761 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -948,7 +948,9 @@ include/grpcpp/impl/channel_argument_option.h \ include/grpcpp/impl/client_unary_call.h \ include/grpcpp/impl/codegen/async_generic_service.h \ include/grpcpp/impl/codegen/async_stream.h \ +include/grpcpp/impl/codegen/async_stream_impl.h \ include/grpcpp/impl/codegen/async_unary_call.h \ +include/grpcpp/impl/codegen/async_unary_call_impl.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ @@ -957,6 +959,7 @@ include/grpcpp/impl/codegen/call_op_set_interface.h \ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ +include/grpcpp/impl/codegen/client_callback_impl.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_context_impl.h \ include/grpcpp/impl/codegen/client_interceptor.h \ @@ -985,6 +988,7 @@ include/grpcpp/impl/codegen/rpc_service_method.h \ include/grpcpp/impl/codegen/security/auth_context.h \ include/grpcpp/impl/codegen/serialization_traits.h \ include/grpcpp/impl/codegen/server_callback.h \ +include/grpcpp/impl/codegen/server_callback_impl.h \ include/grpcpp/impl/codegen/server_context.h \ include/grpcpp/impl/codegen/server_context_impl.h \ include/grpcpp/impl/codegen/server_interceptor.h \ @@ -997,6 +1001,7 @@ include/grpcpp/impl/codegen/string_ref.h \ include/grpcpp/impl/codegen/stub_options.h \ include/grpcpp/impl/codegen/sync.h \ include/grpcpp/impl/codegen/sync_stream.h \ +include/grpcpp/impl/codegen/sync_stream_impl.h \ include/grpcpp/impl/codegen/time.h \ include/grpcpp/impl/grpc_library.h \ include/grpcpp/impl/method_handler_impl.h \ @@ -1026,11 +1031,14 @@ include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ +include/grpcpp/support/async_stream_impl.h \ include/grpcpp/support/async_unary_call.h \ +include/grpcpp/support/async_unary_call_impl.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ +include/grpcpp/support/client_callback_impl.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ include/grpcpp/support/interceptor.h \ @@ -1038,6 +1046,7 @@ include/grpcpp/support/message_allocator.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ include/grpcpp/support/server_callback.h \ +include/grpcpp/support/server_callback_impl.h \ include/grpcpp/support/server_interceptor.h \ include/grpcpp/support/slice.h \ include/grpcpp/support/status.h \ @@ -1045,6 +1054,7 @@ include/grpcpp/support/status_code_enum.h \ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ +include/grpcpp/support/sync_stream_impl.h \ include/grpcpp/support/time.h \ include/grpcpp/support/validate_service_config.h \ src/core/ext/filters/client_channel/health/health.pb.c \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index e638e305af8..fd8037cf3a3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10190,7 +10190,9 @@ "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -10199,6 +10201,7 @@ "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -10221,6 +10224,7 @@ "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -10232,6 +10236,7 @@ "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h" ], "is_filegroup": true, @@ -10270,7 +10275,9 @@ "include/grpc++/impl/codegen/time.h", "include/grpcpp/impl/codegen/async_generic_service.h", "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_stream_impl.h", "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/async_unary_call_impl.h", "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", @@ -10279,6 +10286,7 @@ "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_callback_impl.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_context_impl.h", "include/grpcpp/impl/codegen/client_interceptor.h", @@ -10301,6 +10309,7 @@ "include/grpcpp/impl/codegen/security/auth_context.h", "include/grpcpp/impl/codegen/serialization_traits.h", "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_callback_impl.h", "include/grpcpp/impl/codegen/server_context.h", "include/grpcpp/impl/codegen/server_context_impl.h", "include/grpcpp/impl/codegen/server_interceptor.h", @@ -10312,6 +10321,7 @@ "include/grpcpp/impl/codegen/string_ref.h", "include/grpcpp/impl/codegen/stub_options.h", "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/sync_stream_impl.h", "include/grpcpp/impl/codegen/time.h" ], "third_party": false, @@ -10461,11 +10471,14 @@ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -10473,6 +10486,7 @@ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -10480,6 +10494,7 @@ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/cpp/client/create_channel_internal.h", @@ -10589,11 +10604,14 @@ "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_stream_impl.h", "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/async_unary_call_impl.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_callback_impl.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", "include/grpcpp/support/interceptor.h", @@ -10601,6 +10619,7 @@ "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_callback_impl.h", "include/grpcpp/support/server_interceptor.h", "include/grpcpp/support/slice.h", "include/grpcpp/support/status.h", @@ -10608,6 +10627,7 @@ "include/grpcpp/support/string_ref.h", "include/grpcpp/support/stub_options.h", "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/sync_stream_impl.h", "include/grpcpp/support/time.h", "include/grpcpp/support/validate_service_config.h", "src/cpp/client/channel_cc.cc", From 1487ac42cc992e5e9a9e8dfa0742a74c14593db6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 1 Jul 2019 14:11:44 -0700 Subject: [PATCH 532/676] Remove CMSG_SPACE for macos --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 0e153679ad7..819c5284256 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -443,7 +443,7 @@ static void tcp_do_read(grpc_tcp* tcp) { constexpr size_t cmsg_alloc_space = CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(int)); #else - constexpr size_t cmsg_alloc_space = CMSG_SPACE(sizeof(int)); + constexpr size_t cmsg_alloc_space = 24 /* CMSG_SPACE(sizeof(int)) */; #endif /* GRPC_LINUX_ERRQUEUE */ char cmsgbuf[cmsg_alloc_space]; for (size_t i = 0; i < iov_len; i++) { From 01b82d3a39f2d4455025e9176dae7917a82babb2 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 1 Jul 2019 18:29:54 -0400 Subject: [PATCH 533/676] Return empty strings on optional ports for backward compatibility. gpr_split_host_port returns an empty string for the port when given "0.0.0.0:" as the input. Change the emptiness check to an explicit argument called has_port, to remain backward compatible. Added a test to cover both v4 and v6. --- src/core/lib/gprpp/host_port.cc | 18 +++++++++++++++--- test/core/gprpp/host_port_test.cc | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index 13b63eb902b..3fa4719f49a 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -44,7 +44,10 @@ int JoinHostPort(UniquePtr* out, const char* host, int port) { return ret; } -bool SplitHostPort(StringView name, StringView* host, StringView* port) { +namespace { +bool DoSplitHostPort(StringView name, StringView* host, StringView* port, + bool* has_port) { + *has_port = false; if (name[0] == '[') { /* Parse a bracketed host, typically an IPv6 literal. */ const size_t rbracket = name.find(']', 1); @@ -58,6 +61,7 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { } else if (name[rbracket + 1] == ':') { /* ]: */ *port = name.substr(rbracket + 2, name.size() - rbracket - 2); + *has_port = true; } else { /* ] */ return false; @@ -76,6 +80,7 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { /* Exactly 1 colon. Split into host:port. */ *host = name.substr(0, colon); *port = name.substr(colon + 1, name.size() - colon - 1); + *has_port = true; } else { /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ *host = name; @@ -84,6 +89,12 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { } return true; } +} // namespace + +bool SplitHostPort(StringView name, StringView* host, StringView* port) { + bool unused; + return DoSplitHostPort(name, host, port, &unused); +} bool SplitHostPort(StringView name, UniquePtr* host, UniquePtr* port) { @@ -91,12 +102,13 @@ bool SplitHostPort(StringView name, UniquePtr* host, GPR_DEBUG_ASSERT(port != nullptr && *port == nullptr); StringView host_view; StringView port_view; - const bool ret = SplitHostPort(name, &host_view, &port_view); + bool has_port; + const bool ret = DoSplitHostPort(name, &host_view, &port_view, &has_port); if (ret) { // We always set the host, but port is set only when it's non-empty, // to remain backward compatible with the old split_host_port API. *host = host_view.dup(); - if (!port_view.empty()) { + if (has_port) { *port = port_view.dup(); } } diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc index 3b392da66e8..cfe0eddb036 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -71,7 +71,9 @@ static void test_split_host_port() { split_host_port_expect("", "", nullptr, true); split_host_port_expect("[a:b]", "a:b", nullptr, true); split_host_port_expect("1.2.3.4", "1.2.3.4", nullptr, true); + split_host_port_expect("0.0.0.0:", "0.0.0.0", "", true); split_host_port_expect("a:b:c::", "a:b:c::", nullptr, true); + split_host_port_expect("[a:b:c::]:", "a:b:c::", "", true); split_host_port_expect("[a:b]:30", "a:b", "30", true); split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); split_host_port_expect(":30", "", "30", true); From cac8afa1593cd551e1ea122ba2d07e4166478ee4 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 15:34:24 -0700 Subject: [PATCH 534/676] Add benchmark --- src/core/lib/iomgr/executor/threadpool.h | 13 +- test/cpp/microbenchmarks/BUILD | 8 + test/cpp/microbenchmarks/bm_threadpool.cc | 346 ++++++++++++++++++++++ 3 files changed, 361 insertions(+), 6 deletions(-) create mode 100644 test/cpp/microbenchmarks/bm_threadpool.cc diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index b14f1051feb..f362cea4a16 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -69,9 +69,9 @@ class ThreadPoolWorker { MPMCQueueInterface* queue, Thread::Options& options, int index) : queue_(queue), thd_name_(thd_name), index_(index) { - thd_ = Thread( - thd_name, [](void* th) { static_cast(th)->Run(); }, - this, nullptr, options); + thd_ = Thread(thd_name, + [](void* th) { static_cast(th)->Run(); }, + this, nullptr, options); } ~ThreadPoolWorker() {} @@ -100,7 +100,7 @@ class ThreadPoolWorker { // A fixed size thread pool implementation of abstract thread pool interface. // In this implementation, the number of threads in pool is fixed, but the // capacity of closure queue is unlimited. -class ThreadPool : public ThreadPoolInterface { +class ThreadPool : public ThreadPoolInterface { public: // Creates a thread pool with size of "num_threads", with default thread name // "ThreadPoolWorker" and all thread options set to default. @@ -108,7 +108,7 @@ class ThreadPool : public ThreadPoolInterface { // Same as ThreadPool(int num_threads) constructor, except // that it also sets "thd_name" as the name of all threads in the thread pool. - ThreadPool(int num_threads, const char* thd_name); + ThreadPool(int num_threads, const char *thd_name); // Same as ThreadPool(const char *thd_name, int num_threads) constructor, // except that is also set thread_options for threads. @@ -117,7 +117,7 @@ class ThreadPool : public ThreadPoolInterface { // value 0, default ThreadPool stack size will be used. The current default // stack size of this implementation is 1952K for mobile platform and 64K for // all others. - ThreadPool(int num_threads, const char* thd_name, + ThreadPool(int num_threads, const char *thd_name, const Thread::Options& thread_options); // Waits for all pending closures to complete, then shuts down thread pool. @@ -148,6 +148,7 @@ class ThreadPool : public ThreadPoolInterface { bool HasBeenShutDown(); }; + } // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_THREADPOOL_H */ diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index d9424f24f16..576eab554a4 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -214,6 +214,14 @@ grpc_cc_binary( ], ) +grpc_cc_binary( + name = "bm_threadpool", + testonly = 1, + srcs = ["bm_threadpool.cc"], + tags = ["no_windows"], + deps = [":helpers"], +) + grpc_cc_binary( name = "bm_timer", testonly = 1, diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc new file mode 100644 index 00000000000..9eef16a7026 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_threadpool.cc @@ -0,0 +1,346 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/executor/threadpool.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + + + +namespace grpc { +namespace testing { + +// This helper class allows a thread to block for s pre-specified number of +// actions. BlockingCounter has a initial non-negative count on initialization +// Each call to DecrementCount will decrease the count by 1. When making a call +// to Wait, if the count is greater than 0, the thread will be block, until +// the count reaches 0, it will unblock. +class BlockingCounter { + public: + BlockingCounter(int count) : count_(count) {} + void DecrementCount() { + std::lock_guard l(mu_); + count_--; + cv_.notify_one(); + } + + void Wait() { + std::unique_lock l(mu_); + while (count_ > 0) { + cv_.wait(l); + } + } + private: + int count_; + std::mutex mu_; + std::condition_variable cv_; +}; + +// This is a functor/closure class for threadpool microbenchmark. +// This functor (closure) class will add another functor into pool if the +// number passed in (num_add) is greater than 0. Otherwise, it will decrement +// the counter to indicate that task is finished. This functor will suicide at +// the end, therefore, no need for caller to do clean-ups. +class AddAnotherFunctor : public grpc_experimental_completion_queue_functor { + public: + AddAnotherFunctor(grpc_core::ThreadPool* pool, BlockingCounter* counter, + int num_add) + : pool_(pool), counter_(counter), num_add_(num_add) { + functor_run = &AddAnotherFunctor::Run; + internal_next = this; + internal_success = 0; + } + ~AddAnotherFunctor() {} + // When the functor gets to run in thread pool, it will take internal_next + // as first argument and internal_success as second one. Therefore, the + // first argument here would be the closure itself. + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + auto* callback = static_cast(cb); + if (--callback->num_add_ > 0) { + callback->pool_->Add(new AddAnotherFunctor( + callback->pool_, callback->counter_, callback->num_add_)); + } else { + callback->counter_->DecrementCount(); + } + // Suicide + delete callback; + } + + private: + grpc_core::ThreadPool* pool_; + BlockingCounter* counter_; + int num_add_; +}; + +void ThreadPoolAddAnotherHelper(benchmark::State& state, + int concurrent_functor) { + const int num_threads = state.range(0); + const int num_iterations = state.range(1); + // number of adds done by each closure + const int num_add = num_iterations / concurrent_functor; + grpc_core::ThreadPool pool(num_threads); + while (state.KeepRunningBatch(num_iterations)) { + BlockingCounter* counter = new BlockingCounter(concurrent_functor); + for (int i = 0; i < concurrent_functor; ++i) { + pool.Add(new AddAnotherFunctor(&pool, counter, num_add)); + } + counter->Wait(); + delete counter; + } + state.SetItemsProcessed(state.iterations()); +} + +// This benchmark will let a closure add a new closure into pool. Concurrent +// closures range from 1 to 2048 +static void BM_ThreadPool1AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 1); +} +BENCHMARK(BM_ThreadPool1AddAnother) + ->UseRealTime() + // ->Iterations(1) + // First pair is range for number of threads in pool, second paris is range + // for number of iterations + ->Ranges({{1, 1024}, {524288, 524288}}); // range = 2M ~ 4M + +static void BM_ThreadPool4AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 4); +} +BENCHMARK(BM_ThreadPool4AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); // range = 256K ~ 512K + +static void BM_ThreadPool8AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 8); +} +BENCHMARK(BM_ThreadPool8AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + + +static void BM_ThreadPool16AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 16); +} +BENCHMARK(BM_ThreadPool16AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + + +static void BM_ThreadPool32AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 32); +} +BENCHMARK(BM_ThreadPool32AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + +static void BM_ThreadPool64AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 64); +} +BENCHMARK(BM_ThreadPool64AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + +static void BM_ThreadPool128AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 128); +} +BENCHMARK(BM_ThreadPool128AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + +static void BM_ThreadPool512AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 512); +} +BENCHMARK(BM_ThreadPool512AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + +static void BM_ThreadPool2048AddAnother(benchmark::State& state) { + ThreadPoolAddAnotherHelper(state, 2048); +} +BENCHMARK(BM_ThreadPool2048AddAnother) + ->UseRealTime() + // ->Iterations(1) + ->Ranges({{1, 1024}, {524288, 524288}}); + + +// A functor class that will delete self on end of running. +class SuicideFunctorForAdd + : public grpc_experimental_completion_queue_functor { + public: + SuicideFunctorForAdd() { + functor_run = &SuicideFunctorForAdd::Run; + internal_next = this; + internal_success = 0; + } + ~SuicideFunctorForAdd() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + // On running, the first argument would be internal_next, which is itself. + delete cb; + } +}; + +// Performs the scenario of external thread(s) adding closures into pool. +static void BM_ThreadPoolExternalAdd(benchmark::State& state) { + const int num_threads = state.range(0); + static grpc_core::ThreadPool* pool = + new grpc_core::ThreadPool(num_threads); + for (auto _ : state) { + pool->Add(new SuicideFunctorForAdd()); + } + state.SetItemsProcessed(state.iterations()); +} +BENCHMARK(BM_ThreadPoolExternalAdd) + ->Range(1, 1024) + ->ThreadRange(1, 1024) // concurrent external thread(s) up to 1024 + ->UseRealTime(); + +// Functor (closure) that adds itself into pool repeatedly. By adding self, the +// overhead would be low and can measure the time of add more accurately. +class AddSelfFunctor : public grpc_experimental_completion_queue_functor { + public: + AddSelfFunctor(grpc_core::ThreadPool* pool, BlockingCounter* counter, + int num_add) + : pool_(pool), counter_(counter), num_add_(num_add) { + functor_run = &AddSelfFunctor::Run; + internal_next = this; + internal_success = 0; + } + ~AddSelfFunctor() {} + // When the functor gets to run in thread pool, it will take internal_next + // as first argument and internal_success as second one. Therefore, the + // first argument here would be the closure itself. + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + auto* callback = static_cast(cb); + if (--callback->num_add_ > 0) { + callback->pool_->Add(cb); + } else { + callback->counter_->DecrementCount(); + // Suicide + delete callback; + } + } + + private: + grpc_core::ThreadPool* pool_; + BlockingCounter* counter_; + int num_add_; +}; + +static void BM_ThreadPoolAddSelf(benchmark::State& state) { + const int num_threads = state.range(0); + const int kNumIteration = 524288; + int concurrent_functor = num_threads; + int num_add = kNumIteration / concurrent_functor; + grpc_core::ThreadPool pool(num_threads); + while (state.KeepRunningBatch(kNumIteration)) { + BlockingCounter* counter = new BlockingCounter(concurrent_functor); + for (int i = 0; i < concurrent_functor; ++i) { + pool.Add(new AddSelfFunctor(&pool, counter, num_add)); + } + counter->Wait(); + delete counter; + } + state.SetItemsProcessed(state.iterations()); +} + +BENCHMARK(BM_ThreadPoolAddSelf)->UseRealTime()->Range(1, 1024); + +// A functor (closure) that simulates closures with small but non-trivial amount +// of work. +class ShortWorkFunctorForAdd + : public grpc_experimental_completion_queue_functor { + public: + BlockingCounter* counter_; + + ShortWorkFunctorForAdd() { + functor_run = &ShortWorkFunctorForAdd::Run; + internal_next = this; + internal_success = 0; + val_ = 0; + } + ~ShortWorkFunctorForAdd() {} + static void Run(grpc_experimental_completion_queue_functor *cb, int ok) { + auto* callback = static_cast(cb); + for (int i = 0; i < 1000; ++i) { + callback->val_++; + } + callback->counter_->DecrementCount(); + } + private: + int val_; +}; + +// Simulates workloads where many short running callbacks are added to the +// threadpool. The callbacks are not enough to keep all the workers busy +// continuously so the number of workers running changes overtime. +// +// In effect this tests how well the threadpool avoids spurious wakeups. +static void BM_SpikyLoad(benchmark::State& state) { + const int num_threads = state.range(0); + + const int kNumSpikes = 1000; + const int batch_size = 3 * num_threads; + std::vector work_vector(batch_size); + while (state.KeepRunningBatch(kNumSpikes * batch_size)) { + grpc_core::ThreadPool pool(num_threads); + for (int i = 0; i != kNumSpikes; ++i) { + BlockingCounter counter(batch_size); + for (auto& w : work_vector) { + w.counter_ = &counter; + pool.Add(&w); + } + counter.Wait(); + } + } + state.SetItemsProcessed(state.iterations() * batch_size); +} +BENCHMARK(BM_SpikyLoad)->Arg(1)->Arg(2)->Arg(4)->Arg(8)->Arg(16); + +} // namespace testing +} // namespace grpc + +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + LibraryInitializer libInit; + ::benchmark::Initialize(&argc, argv); + // gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} From 9421a27a76bc9f0100e2ad30f3e299fb9d2c0225 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 15:45:01 -0700 Subject: [PATCH 535/676] Remove extra headers --- test/cpp/microbenchmarks/bm_threadpool.cc | 44 +++++++---------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc index 9eef16a7026..2e68a298b15 100644 --- a/test/cpp/microbenchmarks/bm_threadpool.cc +++ b/test/cpp/microbenchmarks/bm_threadpool.cc @@ -16,22 +16,14 @@ * */ -#include "src/core/lib/iomgr/executor/threadpool.h" - -#include - #include -#include -#include -#include + #include -#include -#include + +#include "src/core/lib/iomgr/executor/threadpool.h" #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" - - namespace grpc { namespace testing { @@ -122,26 +114,23 @@ static void BM_ThreadPool1AddAnother(benchmark::State& state) { } BENCHMARK(BM_ThreadPool1AddAnother) ->UseRealTime() - // ->Iterations(1) - // First pair is range for number of threads in pool, second paris is range + // First pair is range for number of threads in pool, second pair is range // for number of iterations - ->Ranges({{1, 1024}, {524288, 524288}}); // range = 2M ~ 4M + ->Ranges({{1, 1024}, {524288, 2097152}}); // 512K ~ 2M static void BM_ThreadPool4AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 4); } BENCHMARK(BM_ThreadPool4AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); // range = 256K ~ 512K + ->Ranges({{1, 1024}, {524288, 2097152}}); static void BM_ThreadPool8AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 8); } BENCHMARK(BM_ThreadPool8AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); // 512K ~ 1M static void BM_ThreadPool16AddAnother(benchmark::State& state) { @@ -149,8 +138,7 @@ static void BM_ThreadPool16AddAnother(benchmark::State& state) { } BENCHMARK(BM_ThreadPool16AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); static void BM_ThreadPool32AddAnother(benchmark::State& state) { @@ -158,40 +146,35 @@ static void BM_ThreadPool32AddAnother(benchmark::State& state) { } BENCHMARK(BM_ThreadPool32AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); static void BM_ThreadPool64AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 64); } BENCHMARK(BM_ThreadPool64AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); static void BM_ThreadPool128AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 128); } BENCHMARK(BM_ThreadPool128AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); static void BM_ThreadPool512AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 512); } BENCHMARK(BM_ThreadPool512AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); static void BM_ThreadPool2048AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 2048); } BENCHMARK(BM_ThreadPool2048AddAnother) ->UseRealTime() - // ->Iterations(1) - ->Ranges({{1, 1024}, {524288, 524288}}); + ->Ranges({{1, 1024}, {524288, 1048576}}); // A functor class that will delete self on end of running. @@ -339,7 +322,6 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } int main(int argc, char** argv) { LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); - // gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); return 0; From bf9b4c257bdd5f5765fcd9b6c9402d170f75fea8 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 1 Jul 2019 19:13:26 -0400 Subject: [PATCH 536/676] Fix stale comment in split host port. --- src/core/lib/gprpp/host_port.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index 3fa4719f49a..e7f0e4461e9 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -105,8 +105,9 @@ bool SplitHostPort(StringView name, UniquePtr* host, bool has_port; const bool ret = DoSplitHostPort(name, &host_view, &port_view, &has_port); if (ret) { - // We always set the host, but port is set only when it's non-empty, - // to remain backward compatible with the old split_host_port API. + // We always set the host, but port is set only when DoSplitHostPort find a + // port in the string, to remain backward compatible with the old + // gpr_split_host_port API. *host = host_view.dup(); if (has_port) { *port = port_view.dup(); From 093dd768bb52e7eaf37d7bd5e4d59c85c1912945 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 16:48:26 -0700 Subject: [PATCH 537/676] reformat --- test/cpp/microbenchmarks/bm_threadpool.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc index 2e68a298b15..0ef34c2aecc 100644 --- a/test/cpp/microbenchmarks/bm_threadpool.cc +++ b/test/cpp/microbenchmarks/bm_threadpool.cc @@ -197,7 +197,7 @@ class SuicideFunctorForAdd static void BM_ThreadPoolExternalAdd(benchmark::State& state) { const int num_threads = state.range(0); static grpc_core::ThreadPool* pool = - new grpc_core::ThreadPool(num_threads); + grpc_core::New(num_threads); for (auto _ : state) { pool->Add(new SuicideFunctorForAdd()); } @@ -280,6 +280,7 @@ class ShortWorkFunctorForAdd } callback->counter_->DecrementCount(); } + private: int val_; }; From 651a8b0ec2ca8166665c33784c8e6b3230ffa11a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 17:07:57 -0700 Subject: [PATCH 538/676] Change FetchAdd/Sub to Load-Add/Sub-Store --- src/core/lib/iomgr/executor/mpmcqueue.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 97429ec30c7..ea2a6868d2f 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -31,7 +31,7 @@ inline void* InfLenFIFOQueue::PopFront() { Node* head_to_remove = queue_head_; queue_head_ = queue_head_->next; - count_.FetchSub(1, MemoryOrder::RELAXED); + count_.Store(count_.Load(MemoryOrder::RELAXED) - 1, MemoryOrder::RELAXED); if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { gpr_timespec wait_time = @@ -76,7 +76,7 @@ void InfLenFIFOQueue::Put(void* elem) { MutexLock l(&mu_); Node* new_node = New(elem); - if (count_.FetchAdd(1, MemoryOrder::RELAXED) == 0) { + if (count_.Load(MemoryOrder::RELAXED) == 0) { if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { busy_time = gpr_now(GPR_CLOCK_MONOTONIC); } @@ -85,7 +85,7 @@ void InfLenFIFOQueue::Put(void* elem) { queue_tail_->next = new_node; queue_tail_ = queue_tail_->next; } - + count_.Store(count_.Load(MemoryOrder::RELAXED) + 1, MemoryOrder::RELAXED); // Updates Stats info if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { stats_.num_started++; From 500cb1f99b495bcb081c2e6d913dd27493c97815 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 1 Jul 2019 17:58:54 -0700 Subject: [PATCH 539/676] Reformat --- src/core/lib/iomgr/executor/threadpool.h | 10 ++++------ test/cpp/microbenchmarks/bm_threadpool.cc | 11 ++++------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index f362cea4a16..d0822fadc8b 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -19,9 +19,8 @@ #ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H #define GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H -#include - #include +#include #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor/mpmcqueue.h" @@ -100,7 +99,7 @@ class ThreadPoolWorker { // A fixed size thread pool implementation of abstract thread pool interface. // In this implementation, the number of threads in pool is fixed, but the // capacity of closure queue is unlimited. -class ThreadPool : public ThreadPoolInterface { +class ThreadPool : public ThreadPoolInterface { public: // Creates a thread pool with size of "num_threads", with default thread name // "ThreadPoolWorker" and all thread options set to default. @@ -108,7 +107,7 @@ class ThreadPool : public ThreadPoolInterface { // Same as ThreadPool(int num_threads) constructor, except // that it also sets "thd_name" as the name of all threads in the thread pool. - ThreadPool(int num_threads, const char *thd_name); + ThreadPool(int num_threads, const char* thd_name); // Same as ThreadPool(const char *thd_name, int num_threads) constructor, // except that is also set thread_options for threads. @@ -117,7 +116,7 @@ class ThreadPool : public ThreadPoolInterface { // value 0, default ThreadPool stack size will be used. The current default // stack size of this implementation is 1952K for mobile platform and 64K for // all others. - ThreadPool(int num_threads, const char *thd_name, + ThreadPool(int num_threads, const char* thd_name, const Thread::Options& thread_options); // Waits for all pending closures to complete, then shuts down thread pool. @@ -148,7 +147,6 @@ class ThreadPool : public ThreadPoolInterface { bool HasBeenShutDown(); }; - } // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_THREADPOOL_H */ diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc index 0ef34c2aecc..b4ebcdaaf92 100644 --- a/test/cpp/microbenchmarks/bm_threadpool.cc +++ b/test/cpp/microbenchmarks/bm_threadpool.cc @@ -47,6 +47,7 @@ class BlockingCounter { cv_.wait(l); } } + private: int count_; std::mutex mu_; @@ -61,7 +62,7 @@ class BlockingCounter { class AddAnotherFunctor : public grpc_experimental_completion_queue_functor { public: AddAnotherFunctor(grpc_core::ThreadPool* pool, BlockingCounter* counter, - int num_add) + int num_add) : pool_(pool), counter_(counter), num_add_(num_add) { functor_run = &AddAnotherFunctor::Run; internal_next = this; @@ -132,7 +133,6 @@ BENCHMARK(BM_ThreadPool8AddAnother) ->UseRealTime() ->Ranges({{1, 1024}, {524288, 1048576}}); // 512K ~ 1M - static void BM_ThreadPool16AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 16); } @@ -140,7 +140,6 @@ BENCHMARK(BM_ThreadPool16AddAnother) ->UseRealTime() ->Ranges({{1, 1024}, {524288, 1048576}}); - static void BM_ThreadPool32AddAnother(benchmark::State& state) { ThreadPoolAddAnotherHelper(state, 32); } @@ -176,10 +175,8 @@ BENCHMARK(BM_ThreadPool2048AddAnother) ->UseRealTime() ->Ranges({{1, 1024}, {524288, 1048576}}); - // A functor class that will delete self on end of running. -class SuicideFunctorForAdd - : public grpc_experimental_completion_queue_functor { +class SuicideFunctorForAdd : public grpc_experimental_completion_queue_functor { public: SuicideFunctorForAdd() { functor_run = &SuicideFunctorForAdd::Run; @@ -273,7 +270,7 @@ class ShortWorkFunctorForAdd val_ = 0; } ~ShortWorkFunctorForAdd() {} - static void Run(grpc_experimental_completion_queue_functor *cb, int ok) { + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { auto* callback = static_cast(cb); for (int i = 0; i < 1000; ++i) { callback->val_++; From aa535356e8a95d686396f79370f500c3be8e6233 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 08:28:44 +0100 Subject: [PATCH 540/676] fix encode benchmark (and simplify decode benchmark) --- src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs | 20 +++---- src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 54 +++++++++++-------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs index 1c3f4d261ee..070f8ec03ce 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -11,15 +11,18 @@ namespace Grpc.Microbenchmarks public class Utf8Decode { [Params(0, 1, 4, 128, 1024)] - public int PayloadSize { get; set; } + public int PayloadSize + { + get { return payloadSize; } + set + { + payloadSize = value; + payload = Invent(value); + } + } - static readonly Dictionary Payloads = new Dictionary { - { 0, Invent(0) }, - { 1, Invent(1) }, - { 4, Invent(4) }, - { 128, Invent(128) }, - { 1024, Invent(1024) }, - }; + private int payloadSize; + private byte[] payload; static byte[] Invent(int length) { @@ -36,7 +39,6 @@ namespace Grpc.Microbenchmarks [Benchmark(OperationsPerInvoke = Iterations)] public unsafe void Run() { - byte[] payload = Payloads[PayloadSize]; fixed (byte* ptr = payload) { var iPtr = new IntPtr(ptr); diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index 0c9370679a4..bf9fe68e467 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -10,16 +10,19 @@ namespace Grpc.Microbenchmarks [MemoryDiagnoser] // allocations public class Utf8Encode : ISendStatusFromServerCompletionCallback { - [Params(0)] //, 1, 4, 128, 1024)] - public int PayloadSize { get; set; } + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize + { + get { return payloadSize; } + set + { + payloadSize = value; + status = new Status(StatusCode.OK, Invent(value)); + } + } - static readonly Dictionary Payloads = new Dictionary { - { 0, Invent(0) }, - { 1, Invent(1) }, - { 4, Invent(4) }, - { 128, Invent(128) }, - { 1024, Invent(1024) }, - }; + private int payloadSize; + private Status status; static string Invent(int length) { @@ -33,19 +36,22 @@ namespace Grpc.Microbenchmarks } private GrpcEnvironment environment; - + private CompletionRegistry completionRegistry; [GlobalSetup] public void Setup() { var native = NativeMethods.Get(); // nop the native-call via reflection - NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => CallError.OK; + NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { + completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go + return CallError.OK; + }; native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); environment = GrpcEnvironment.AddRef(); metadata = MetadataArraySafeHandle.Create(Metadata.Empty); - var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); + completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); call = CreateFakeCall(cq); } @@ -65,15 +71,23 @@ namespace Grpc.Microbenchmarks [GlobalCleanup] public void Cleanup() { - metadata?.Dispose(); - metadata = null; - call?.Dispose(); - call = null; + try + { + metadata?.Dispose(); + metadata = null; + call?.Dispose(); + call = null; - if (environment != null) + if (environment != null) + { + environment = null; + // cleanup seems... unreliable on CLR + // GrpcEnvironment.ReleaseAsync().Wait(1000); + } + } + catch (Exception ex) { - environment = null; - GrpcEnvironment.ReleaseAsync().Wait(); + Console.Error.WriteLine(ex.Message); } } private CallSafeHandle call; @@ -83,8 +97,6 @@ namespace Grpc.Microbenchmarks [Benchmark(OperationsPerInvoke = Iterations)] public unsafe void Run() { - string payload = Payloads[PayloadSize]; - var status = new Status(StatusCode.OK, payload); for (int i = 0; i < Iterations; i++) { call.StartSendStatusFromServer(this, status, metadata, false, null, WriteFlags.NoCompress); From 36c1a11d84771eec759a92670c071744c7541c96 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 08:48:24 +0100 Subject: [PATCH 541/676] give useful names to benchmarks --- grpcpp_channelz.vcxproj.filters | 42 +++++++++++++++++++ .../CompletionRegistryBenchmark.cs | 2 +- .../PInvokeByteArrayBenchmark.cs | 2 +- .../SendMessageBenchmark.cs | 4 +- src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs | 2 +- src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 2 +- 6 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 grpcpp_channelz.vcxproj.filters diff --git a/grpcpp_channelz.vcxproj.filters b/grpcpp_channelz.vcxproj.filters new file mode 100644 index 00000000000..9f37e96eb69 --- /dev/null +++ b/grpcpp_channelz.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + CMake Rules + + + + + + {870DBD13-69C5-3F27-A253-623E8947E2E7} + + + {67AA517E-A3B4-3BFF-B690-252465A3B876} + + + {B3AFD131-5BE8-3F8D-8C68-1BD558A25862} + + + diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index 58ba29927cc..ac252a95d89 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -29,7 +29,7 @@ namespace Grpc.Microbenchmarks const int Iterations = 1000; [Benchmark(OperationsPerInvoke = Iterations)] - public void Run() + public void RegisterExtract() { RunConcurrent(() => { CompletionRegistry sharedRegistry = UseSharedRegistry ? new CompletionRegistry(Environment, () => BatchContextSafeHandle.Create(), () => RequestCallContextSafeHandle.Create()) : null; diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs index 412f9ad1cb4..b217aef2068 100644 --- a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs @@ -34,7 +34,7 @@ namespace Grpc.Microbenchmarks const int Iterations = 1000; [Benchmark(OperationsPerInvoke = Iterations)] - public void Run() + public void AllocFree() { RunConcurrent(RunBody); } diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index fa06e7a8230..56ae838a4f4 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Copyright 2015 gRPC authors. // @@ -38,7 +38,7 @@ namespace Grpc.Microbenchmarks const int Iterations = 1000; [Benchmark(OperationsPerInvoke = Iterations)] - public void Run() + public void SendMessage() { RunConcurrent(RunBody); } diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs index 070f8ec03ce..5c5c927a260 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -37,7 +37,7 @@ namespace Grpc.Microbenchmarks const int Iterations = 1000; [Benchmark(OperationsPerInvoke = Iterations)] - public unsafe void Run() + public unsafe void Decode() { fixed (byte* ptr = payload) { diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index bf9fe68e467..95e7ad45841 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -95,7 +95,7 @@ namespace Grpc.Microbenchmarks const int Iterations = 1000; [Benchmark(OperationsPerInvoke = Iterations)] - public unsafe void Run() + public unsafe void SendStatus() { for (int i = 0; i < Iterations; i++) { From dd5f19765ea382b6ae1b08b786c448c923597a5c Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 09:11:14 +0100 Subject: [PATCH 542/676] add framework overhead "PingBenchmark" --- .../Grpc.Microbenchmarks/PingBenchmark.cs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs diff --git a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs new file mode 100644 index 00000000000..25996fb6868 --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs @@ -0,0 +1,84 @@ +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using Grpc.Core; + +namespace Grpc.Microbenchmarks +{ + // this test creates a real server and client, measuring the inherent inbuilt + // platform overheads; the marshallers **DO NOT ALLOCATE**, so any allocations + // are from the framework, not the messages themselves + + // important: allocs are not reliable on .NET Core until .NET Core 3, since + // this test involves multiple threads + + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class PingBenchmark + { + private static readonly Task CompletedString = Task.FromResult(""); + private static readonly byte[] EmptyBlob = new byte[0]; + private static readonly Marshaller EmptyMarshaller = new Marshaller(_ => EmptyBlob, _ => ""); + private static readonly Method PingMethod = new Method(MethodType.Unary, nameof(PingBenchmark), "Ping", EmptyMarshaller, EmptyMarshaller); + + + [Benchmark] + public async ValueTask PingAsync() + { + using (var result = client.PingAsync("")) + { + return await result.ResponseAsync; + } + } + + [Benchmark] + public string Ping() + { + return client.Ping(""); + } + + private Task ServerMethod(string request, ServerCallContext context) + { + return CompletedString; + } + + Server server; + Channel channel; + PingClient client; + + [GlobalSetup] + public async Task Setup() + { + // create server + server = new Server { + Ports = { new ServerPort("localhost", 10042, ServerCredentials.Insecure) }, + Services = { ServerServiceDefinition.CreateBuilder().AddMethod(PingMethod, ServerMethod).Build() }, + }; + server.Start(); + + // create client + channel = new Channel("localhost", 10042, ChannelCredentials.Insecure); + await channel.ConnectAsync(); + client = new PingClient(new DefaultCallInvoker(channel)); + } + + [GlobalCleanup] + public async Task Cleanup() + { + await channel.ShutdownAsync(); + await server.ShutdownAsync(); + } + + class PingClient : LiteClientBase + { + public PingClient(CallInvoker callInvoker) : base(callInvoker) { } + public AsyncUnaryCall PingAsync(string request, CallOptions options = default) + { + return CallInvoker.AsyncUnaryCall(PingMethod, null, options, request); + } + public string Ping(string request, CallOptions options = default) + { + return CallInvoker.BlockingUnaryCall(PingMethod, null, options, request); + } + } + } +} From ffac31b10830c763c2e04c71d7eaf038e405d318 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 09:30:26 +0100 Subject: [PATCH 543/676] incorrectly added --- grpcpp_channelz.vcxproj.filters | 42 --------------------------------- 1 file changed, 42 deletions(-) delete mode 100644 grpcpp_channelz.vcxproj.filters diff --git a/grpcpp_channelz.vcxproj.filters b/grpcpp_channelz.vcxproj.filters deleted file mode 100644 index 9f37e96eb69..00000000000 --- a/grpcpp_channelz.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - CMake Rules - - - - - - {870DBD13-69C5-3F27-A253-623E8947E2E7} - - - {67AA517E-A3B4-3BFF-B690-252465A3B876} - - - {B3AFD131-5BE8-3F8D-8C68-1BD558A25862} - - - From a56998bdffa4ed97615649d5f9e6ba908ced4260 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Jul 2019 03:35:12 -0400 Subject: [PATCH 544/676] fix small nits --- src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs | 2 +- src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs index 4b6174eeef8..c6bdf471b8a 100644 --- a/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs +++ b/src/csharp/Grpc.Microbenchmarks/CommonThreadedBase.cs @@ -35,7 +35,7 @@ namespace Grpc.Microbenchmarks { protected virtual bool NeedsEnvironment => true; - [Params(1, 1, 2, 4, 8, 12)] + [Params(1, 2, 4, 8, 12)] public int ThreadCount { get; set; } protected GrpcEnvironment Environment { get; private set; } diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index ac252a95d89..62665925f62 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -22,7 +22,7 @@ using Grpc.Core.Internal; namespace Grpc.Microbenchmarks { - public class CompletionRegistryBenchmarks : CommonThreadedBase + public class CompletionRegistryBenchmark : CommonThreadedBase { [Params(false, true)] public bool UseSharedRegistry { get; set; } From 43240238d2eb0b5df40ee0ca5b8c570ad9e4faec Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Jul 2019 07:17:05 -0400 Subject: [PATCH 545/676] tweak iteration counts for multithreaded benchmarks --- src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs | 2 +- src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs | 2 +- src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs index 62665925f62..e4cd7eeb1f6 100644 --- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -27,7 +27,7 @@ namespace Grpc.Microbenchmarks [Params(false, true)] public bool UseSharedRegistry { get; set; } - const int Iterations = 1000; + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. [Benchmark(OperationsPerInvoke = Iterations)] public void RegisterExtract() { diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs index b217aef2068..de4e635580f 100644 --- a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs @@ -32,7 +32,7 @@ namespace Grpc.Microbenchmarks [Params(0)] public int PayloadSize { get; set; } - const int Iterations = 1000; + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. [Benchmark(OperationsPerInvoke = Iterations)] public void AllocFree() { diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index 56ae838a4f4..d9554db00db 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -36,7 +36,7 @@ namespace Grpc.Microbenchmarks [Params(0)] public int PayloadSize { get; set; } - const int Iterations = 1000; + const int Iterations = 1000000; // High number to make the overhead of RunConcurrent negligible. [Benchmark(OperationsPerInvoke = Iterations)] public void SendMessage() { From 3ba99a685ed548c236f9bcad3061b34dd6e905b5 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Jul 2019 07:20:28 -0400 Subject: [PATCH 546/676] make pingbenchmark compile --- src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs index 25996fb6868..f22c52c8927 100644 --- a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs @@ -24,7 +24,7 @@ namespace Grpc.Microbenchmarks [Benchmark] public async ValueTask PingAsync() { - using (var result = client.PingAsync("")) + using (var result = client.PingAsync("", new CallOptions())) { return await result.ResponseAsync; } @@ -33,7 +33,7 @@ namespace Grpc.Microbenchmarks [Benchmark] public string Ping() { - return client.Ping(""); + return client.Ping("", new CallOptions()); } private Task ServerMethod(string request, ServerCallContext context) @@ -71,11 +71,11 @@ namespace Grpc.Microbenchmarks class PingClient : LiteClientBase { public PingClient(CallInvoker callInvoker) : base(callInvoker) { } - public AsyncUnaryCall PingAsync(string request, CallOptions options = default) + public AsyncUnaryCall PingAsync(string request, CallOptions options) { return CallInvoker.AsyncUnaryCall(PingMethod, null, options, request); } - public string Ping(string request, CallOptions options = default) + public string Ping(string request, CallOptions options) { return CallInvoker.BlockingUnaryCall(PingMethod, null, options, request); } From 47287e8ed7c3d458bbbf326a2434621c20526fdc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Jul 2019 08:02:23 -0400 Subject: [PATCH 547/676] add license headers --- .../Grpc.Microbenchmarks/PingBenchmark.cs | 18 ++++++++++++++++++ src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs | 18 ++++++++++++++++++ src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs index f22c52c8927..3949040aac0 100644 --- a/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/PingBenchmark.cs @@ -1,3 +1,21 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Grpc.Core; diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs index 5c5c927a260..70bbae6f400 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -1,3 +1,21 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + using System; using System.Collections.Generic; using System.Text; diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index 95e7ad45841..3eddb33788a 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -1,3 +1,21 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + using System; using System.Collections.Generic; using BenchmarkDotNet.Attributes; From 6f315691da46b12d1b1728fd8643e36e2de97a78 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 13:57:50 +0100 Subject: [PATCH 548/676] remove boxing of Timespec caused by Equals usage --- src/csharp/Grpc.Core/Internal/Timespec.cs | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs index 71628d50642..ac7b2f720fe 100644 --- a/src/csharp/Grpc.Core/Internal/Timespec.cs +++ b/src/csharp/Grpc.Core/Internal/Timespec.cs @@ -25,8 +25,50 @@ namespace Grpc.Core.Internal /// gpr_timespec from grpc/support/time.h /// [StructLayout(LayoutKind.Sequential)] - internal struct Timespec + internal struct Timespec : IEquatable { + /// + /// Indicates whether this instance and a specified object are equal. + /// + public override bool Equals(object obj) + { + return obj is Timespec && Equals((Timespec)obj); + } + + /// + /// Returns the hash code for this instance. + /// + public override int GetHashCode() + { + unchecked + { + const int Prime = 373587911; + int i = (int)clock_type; + i = (i * Prime) ^ tv_nsec; + i = (i * Prime) ^ tv_nsec.GetHashCode(); + return i; + } + } + + /// + /// Returns the full type name of this instance. + /// + public override string ToString() + { + base.ToString(); + return typeof(Timespec).FullName; + } + + /// + /// Indicates whether this instance and a specified object are equal. + /// + public bool Equals(Timespec other) + { + return this.clock_type == other.clock_type + && this.tv_nsec == other.tv_nsec + && this.tv_sec == other.tv_sec; + } + const long NanosPerSecond = 1000 * 1000 * 1000; const long NanosPerTick = 100; const long TicksPerSecond = NanosPerSecond / NanosPerTick; From 746287111d207445289b6cd06a03ecf662dd3e16 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 14:05:50 +0100 Subject: [PATCH 549/676] (left a base-call in that I'd used to get the intellisense comment) --- src/csharp/Grpc.Core/Internal/Timespec.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs index ac7b2f720fe..0edaffb9f49 100644 --- a/src/csharp/Grpc.Core/Internal/Timespec.cs +++ b/src/csharp/Grpc.Core/Internal/Timespec.cs @@ -55,7 +55,6 @@ namespace Grpc.Core.Internal /// public override string ToString() { - base.ToString(); return typeof(Timespec).FullName; } From 36ecd052f6e8a7fb07cf026d63ea462033033af8 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 14:20:09 +0100 Subject: [PATCH 550/676] avoid capture-context in HandleNewServerRpc => HandleCallAsync --- src/csharp/Grpc.Core/Server.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 26d182ae53b..81b4b59528b 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -334,7 +334,7 @@ namespace Grpc.Core /// /// Selects corresponding handler for given call and handles the call. /// - private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) + private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) { try { @@ -351,7 +351,7 @@ namespace Grpc.Core } finally { - continuation(); + continuation(cq); } } @@ -374,7 +374,7 @@ namespace Grpc.Core // Don't await, the continuations will run on gRPC thread pool once triggered // by cq.Next(). #pragma warning disable 4014 - HandleCallAsync(newRpc, cq, () => AllowOneRpc(cq)); + HandleCallAsync(newRpc, cq, state => AllowOneRpc(state)); #pragma warning restore 4014 } } From 834a3d29a656b5f1e2313e1608bc6f60c2fd21cd Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 14:24:24 +0100 Subject: [PATCH 551/676] capture the server too --- src/csharp/Grpc.Core/Server.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 81b4b59528b..8705f52666f 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -334,7 +334,7 @@ namespace Grpc.Core /// /// Selects corresponding handler for given call and handles the call. /// - private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) + private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq, Action continuation) { try { @@ -351,7 +351,7 @@ namespace Grpc.Core } finally { - continuation(cq); + continuation(this, cq); } } @@ -374,7 +374,7 @@ namespace Grpc.Core // Don't await, the continuations will run on gRPC thread pool once triggered // by cq.Next(). #pragma warning disable 4014 - HandleCallAsync(newRpc, cq, state => AllowOneRpc(state)); + HandleCallAsync(newRpc, cq, (server, state) => server.AllowOneRpc(state)); #pragma warning restore 4014 } } From 264fca1eb6f0bc5118986c38bf53d39bbe02bf7a Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 15:40:36 +0100 Subject: [PATCH 552/676] match delegate signature in benchmark --- src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index 3eddb33788a..990f6fbb48e 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -61,11 +61,14 @@ namespace Grpc.Microbenchmarks var native = NativeMethods.Get(); // nop the native-call via reflection - NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { - completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go - return CallError.OK; - }; - native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); + unsafe + { + NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { + completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go + return CallError.OK; + }; + native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); + } environment = GrpcEnvironment.AddRef(); metadata = MetadataArraySafeHandle.Create(Metadata.Empty); From e95f3297aa3b7b52912e95f6fbe713af1c8328ba Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 16:37:13 +0100 Subject: [PATCH 553/676] don't allocate/copy a buffer in ReadMetadataFromPtrUnsafe unless we actually need to (move that logic to CreateUnsafe); implement well-known strings check (just "user-agent" at the moment) --- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 3 +- src/csharp/Grpc.Core.Api/Metadata.cs | 36 ++++++++++++-- .../Grpc.Core.Tests/Grpc.Core.Tests.csproj | 3 +- src/csharp/Grpc.Core.Tests/MetadataTest.cs | 30 +++++++----- .../Internal/MetadataArraySafeHandle.cs | 47 ++++++++++++++++--- 5 files changed, 95 insertions(+), 24 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 8a32bc757df..0a958299ec8 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -1,4 +1,4 @@ - + @@ -11,6 +11,7 @@ https://github.com/grpc/grpc gRPC RPC HTTP/2 $(GrpcCsharpVersion) + true diff --git a/src/csharp/Grpc.Core.Api/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs index 27e72fbfa8b..7a04a2ee859 100644 --- a/src/csharp/Grpc.Core.Api/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -17,6 +17,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; @@ -345,15 +346,44 @@ namespace Grpc.Core /// Creates a binary value or ascii value metadata entry from data received from the native layer. /// We trust C core to give us well-formed data, so we don't perform any checks or defensive copying. /// - internal static Entry CreateUnsafe(string key, byte[] valueBytes) + internal static unsafe Entry CreateUnsafe(string key, byte* source, int length) { if (HasBinaryHeaderSuffix(key)) { - return new Entry(key, null, valueBytes); + byte[] arr; + if (length == 0) + { + arr = EmptyBlob; + } + else + { // create a local copy in a fresh array + arr = new byte[length]; + Marshal.Copy(new IntPtr(source), arr, 0, length); + } + return new Entry(key, null, arr); + } + else + { + string s; + if (length == 0) + { + s = ""; + } + else + { + int charCount = EncodingASCII.GetCharCount(source, length); + s = new string('\0', charCount); + fixed (char* cPtr = s) + { + EncodingASCII.GetChars(source, length, cPtr, charCount); + } + } + return new Entry(key, s, null); } - return new Entry(key, EncodingASCII.GetString(valueBytes), null); } + static readonly byte[] EmptyBlob = new byte[0]; + private static string NormalizeKey(string key) { GrpcPreconditions.CheckNotNull(key, "key"); diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 7fef2c77091..693646bea1c 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -6,6 +6,7 @@ net45;netcoreapp2.1 Exe true + true diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs index d85d7572a63..7286f9c9932 100644 --- a/src/csharp/Grpc.Core.Tests/MetadataTest.cs +++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs @@ -111,25 +111,31 @@ namespace Grpc.Core.Tests } [Test] - public void Entry_CreateUnsafe_Ascii() + public unsafe void Entry_CreateUnsafe_Ascii() { var bytes = new byte[] { (byte)'X', (byte)'y' }; - var entry = Metadata.Entry.CreateUnsafe("abc", bytes); - Assert.IsFalse(entry.IsBinary); - Assert.AreEqual("abc", entry.Key); - Assert.AreEqual("Xy", entry.Value); - CollectionAssert.AreEqual(bytes, entry.ValueBytes); + fixed (byte* ptr = bytes) + { + var entry = Metadata.Entry.CreateUnsafe("abc", ptr, bytes.Length); + Assert.IsFalse(entry.IsBinary); + Assert.AreEqual("abc", entry.Key); + Assert.AreEqual("Xy", entry.Value); + CollectionAssert.AreEqual(bytes, entry.ValueBytes); + } } [Test] - public void Entry_CreateUnsafe_Binary() + public unsafe void Entry_CreateUnsafe_Binary() { var bytes = new byte[] { 1, 2, 3 }; - var entry = Metadata.Entry.CreateUnsafe("abc-bin", bytes); - Assert.IsTrue(entry.IsBinary); - Assert.AreEqual("abc-bin", entry.Key); - Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); - CollectionAssert.AreEqual(bytes, entry.ValueBytes); + fixed (byte* ptr = bytes) + { + var entry = Metadata.Entry.CreateUnsafe("abc-bin", ptr, bytes.Length); + Assert.IsTrue(entry.IsBinary); + Assert.AreEqual("abc-bin", entry.Key); + Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); + CollectionAssert.AreEqual(bytes, entry.ValueBytes); + } } [Test] diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs index 13fde68fe0f..1663a9d44ac 100644 --- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs @@ -15,8 +15,7 @@ #endregion using System; using System.Runtime.InteropServices; -using System.Threading.Tasks; -using Grpc.Core.Profiling; +using System.Text; namespace Grpc.Core.Internal { @@ -51,7 +50,7 @@ namespace Grpc.Core.Internal /// /// Reads metadata from pointer to grpc_metadata_array /// - public static Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray) + public static unsafe Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray) { if (metadataArray == IntPtr.Zero) { @@ -66,16 +65,50 @@ namespace Grpc.Core.Internal var index = new UIntPtr(i); UIntPtr keyLen; IntPtr keyPtr = Native.grpcsharp_metadata_array_get_key(metadataArray, index, out keyLen); - string key = Marshal.PtrToStringAnsi(keyPtr, (int)keyLen.ToUInt32()); + int keyLen32 = checked((int)keyLen.ToUInt32()); + string key = WellKnownStrings.TryIdentify((byte*)keyPtr.ToPointer(), keyLen32) + ?? Marshal.PtrToStringAnsi(keyPtr, keyLen32); UIntPtr valueLen; IntPtr valuePtr = Native.grpcsharp_metadata_array_get_value(metadataArray, index, out valueLen); - var bytes = new byte[valueLen.ToUInt64()]; - Marshal.Copy(valuePtr, bytes, 0, bytes.Length); - metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes)); + int len32 = checked((int)valueLen.ToUInt64()); + metadata.Add(Metadata.Entry.CreateUnsafe(key, (byte*)valuePtr.ToPointer(), len32)); } return metadata; } + private static class WellKnownStrings + { + // turn a string of ASCII-length 8 into a ulong using the CPUs current + // endianness; this allows us to do the same thing in TryIdentify, + // testing string prefixes (of length >= 8) in a single load/compare + private static unsafe ulong Thunk8(string value) + { + int byteCount = Encoding.ASCII.GetByteCount(value); + if (byteCount != 8) throw new ArgumentException(nameof(value)); + ulong result = 0; + fixed (char* cPtr = value) + { + Encoding.ASCII.GetBytes(cPtr, value.Length, (byte*)&result, byteCount); + } + return result; + } + private static readonly ulong UserAgent = Thunk8("user-age"); + public static unsafe string TryIdentify(byte* source, int length) + { + switch (length) + { + case 10: + // test the first 8 bytes via evilness + ulong first8 = *(ulong*)source; + if (first8 == UserAgent & source[8] == (byte)'n' & source[9] == (byte)'t') + return "user-agent"; + + break; + } + return null; + } + } + internal IntPtr Handle { get From be186ac8d93385c725f0b5403f9bb703aed95480 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 2 Jul 2019 09:55:31 -0700 Subject: [PATCH 554/676] Fix guards name --- src/core/lib/iomgr/executor/threadpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index d0822fadc8b..b0dfa37383b 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -149,4 +149,4 @@ class ThreadPool : public ThreadPoolInterface { } // namespace grpc_core -#endif /* GRPC_CORE_LIB_IOMGR_THREADPOOL_THREADPOOL_H */ +#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H */ From a63cbfb61e393e077cca39101fb3490253f3ec90 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 2 Jul 2019 10:25:22 -0700 Subject: [PATCH 555/676] Fix headers order --- src/core/lib/iomgr/executor/threadpool.h | 3 ++- test/cpp/microbenchmarks/bm_threadpool.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index b0dfa37383b..2ea1d5fcef4 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -19,9 +19,10 @@ #ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H #define GRPC_CORE_LIB_IOMGR_EXECUTOR_THREADPOOL_H -#include #include +#include + #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/executor/mpmcqueue.h" diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc index b4ebcdaaf92..601108aacab 100644 --- a/test/cpp/microbenchmarks/bm_threadpool.cc +++ b/test/cpp/microbenchmarks/bm_threadpool.cc @@ -16,11 +16,12 @@ * */ +#include "src/core/lib/iomgr/executor/threadpool.h" + #include #include -#include "src/core/lib/iomgr/executor/threadpool.h" #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" From 64871bfea254b7694518438920c3376b97235754 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 2 Jul 2019 14:30:34 -0400 Subject: [PATCH 556/676] Revert "Fix stale comment in split host port." This reverts commit bf9b4c257bdd5f5765fcd9b6c9402d170f75fea8. --- src/core/lib/gprpp/host_port.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index e7f0e4461e9..3fa4719f49a 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -105,9 +105,8 @@ bool SplitHostPort(StringView name, UniquePtr* host, bool has_port; const bool ret = DoSplitHostPort(name, &host_view, &port_view, &has_port); if (ret) { - // We always set the host, but port is set only when DoSplitHostPort find a - // port in the string, to remain backward compatible with the old - // gpr_split_host_port API. + // We always set the host, but port is set only when it's non-empty, + // to remain backward compatible with the old split_host_port API. *host = host_view.dup(); if (has_port) { *port = port_view.dup(); From 6376cc9b8f4c1b684ac6b551cb9a8ea1705acd5a Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 2 Jul 2019 14:30:41 -0400 Subject: [PATCH 557/676] Revert "Return empty strings on optional ports for backward compatibility." This reverts commit 01b82d3a39f2d4455025e9176dae7917a82babb2. --- src/core/lib/gprpp/host_port.cc | 18 +++--------------- test/core/gprpp/host_port_test.cc | 2 -- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index 3fa4719f49a..13b63eb902b 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -44,10 +44,7 @@ int JoinHostPort(UniquePtr* out, const char* host, int port) { return ret; } -namespace { -bool DoSplitHostPort(StringView name, StringView* host, StringView* port, - bool* has_port) { - *has_port = false; +bool SplitHostPort(StringView name, StringView* host, StringView* port) { if (name[0] == '[') { /* Parse a bracketed host, typically an IPv6 literal. */ const size_t rbracket = name.find(']', 1); @@ -61,7 +58,6 @@ bool DoSplitHostPort(StringView name, StringView* host, StringView* port, } else if (name[rbracket + 1] == ':') { /* ]: */ *port = name.substr(rbracket + 2, name.size() - rbracket - 2); - *has_port = true; } else { /* ] */ return false; @@ -80,7 +76,6 @@ bool DoSplitHostPort(StringView name, StringView* host, StringView* port, /* Exactly 1 colon. Split into host:port. */ *host = name.substr(0, colon); *port = name.substr(colon + 1, name.size() - colon - 1); - *has_port = true; } else { /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ *host = name; @@ -89,12 +84,6 @@ bool DoSplitHostPort(StringView name, StringView* host, StringView* port, } return true; } -} // namespace - -bool SplitHostPort(StringView name, StringView* host, StringView* port) { - bool unused; - return DoSplitHostPort(name, host, port, &unused); -} bool SplitHostPort(StringView name, UniquePtr* host, UniquePtr* port) { @@ -102,13 +91,12 @@ bool SplitHostPort(StringView name, UniquePtr* host, GPR_DEBUG_ASSERT(port != nullptr && *port == nullptr); StringView host_view; StringView port_view; - bool has_port; - const bool ret = DoSplitHostPort(name, &host_view, &port_view, &has_port); + const bool ret = SplitHostPort(name, &host_view, &port_view); if (ret) { // We always set the host, but port is set only when it's non-empty, // to remain backward compatible with the old split_host_port API. *host = host_view.dup(); - if (has_port) { + if (!port_view.empty()) { *port = port_view.dup(); } } diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc index cfe0eddb036..3b392da66e8 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -71,9 +71,7 @@ static void test_split_host_port() { split_host_port_expect("", "", nullptr, true); split_host_port_expect("[a:b]", "a:b", nullptr, true); split_host_port_expect("1.2.3.4", "1.2.3.4", nullptr, true); - split_host_port_expect("0.0.0.0:", "0.0.0.0", "", true); split_host_port_expect("a:b:c::", "a:b:c::", nullptr, true); - split_host_port_expect("[a:b:c::]:", "a:b:c::", "", true); split_host_port_expect("[a:b]:30", "a:b", "30", true); split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); split_host_port_expect(":30", "", "30", true); From def083b2c84f03d588bf0f9e75323f270c549676 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 2 Jul 2019 14:37:54 -0400 Subject: [PATCH 558/676] Clearly callout the behavior for listening ports. This is to clarify that the port number is a required part of the listening address. --- include/grpcpp/server_builder_impl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 7f85e807d07..9c69adc9147 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -112,6 +112,10 @@ class ServerBuilder { /// /// It can be invoked multiple times. /// + /// If port is not provided in the \a addr (e.g., "1.2.3.4:" or "1.2.3.4"), + /// the default port (i.e., https) is used. To request an ephemeral port, + /// \a addr must include 0 as the port number (e.g., "1.2.3.4:0"). + /// /// \param addr_uri The address to try to bind to the server in URI form. If /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 From f757028ea41b7d6ddb46de4da6e3030da0bdbceb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 2 Jul 2019 11:54:57 -0700 Subject: [PATCH 559/676] Sched combiner closures instead of running to avoid data races --- .../transport/chttp2/transport/chttp2_transport.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 48c3d002bbd..b05a48a6a0c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1232,10 +1232,10 @@ static grpc_closure* add_closure_barrier(grpc_closure* closure) { return closure; } -static void null_then_run_closure(grpc_closure** closure, grpc_error* error) { +static void null_then_sched_closure(grpc_closure** closure, grpc_error* error) { grpc_closure* c = *closure; *closure = nullptr; - GRPC_CLOSURE_RUN(c, error); + GRPC_CLOSURE_SCHED(c, error); } void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, @@ -1902,7 +1902,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t, } grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], s->recv_initial_metadata); - null_then_run_closure(&s->recv_initial_metadata_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_initial_metadata_ready, GRPC_ERROR_NONE); } } @@ -1982,10 +1982,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, s->unprocessed_incoming_frames_buffer_cached_length = s->unprocessed_incoming_frames_buffer.length; if (error == GRPC_ERROR_NONE && *s->recv_message != nullptr) { - null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_message_ready, GRPC_ERROR_NONE); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = nullptr; - null_then_run_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_message_ready, GRPC_ERROR_NONE); } GRPC_ERROR_UNREF(error); } @@ -2051,8 +2051,8 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, s->collecting_stats = nullptr; grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], s->recv_trailing_metadata); - null_then_run_closure(&s->recv_trailing_metadata_finished, - GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_trailing_metadata_finished, + GRPC_ERROR_NONE); } } } From d8c01823606f5ff1597b3316183c01ceef57c49a Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 2 Jul 2019 12:32:14 -0700 Subject: [PATCH 560/676] Expose some of the internal codegen interfaces --- include/grpcpp/impl/codegen/async_stream.h | 30 ++++++++++++++ .../grpcpp/impl/codegen/async_unary_call.h | 10 +++++ include/grpcpp/impl/codegen/client_callback.h | 12 ++++++ include/grpcpp/impl/codegen/sync_stream.h | 39 +++++++++++++++++++ third_party/googletest | 2 +- third_party/protobuf | 2 +- 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index 14dfe67962e..d76a8982a4b 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -22,6 +22,20 @@ #include namespace grpc { + +namespace internal { + +typedef ::grpc_impl::internal::ClientAsyncStreamingInterface + ClientAsyncStreamingInterface; + +template +using AsyncReaderInterface = ::grpc_impl::internal::AsyncReaderInterface; + +template +using AsyncWriterInterface = ::grpc_impl::internal::AsyncWriterInterface; + +} // namespace internal + template using ClientAsyncReaderInterface = ::grpc_impl::ClientAsyncReaderInterface; @@ -60,6 +74,22 @@ using ServerAsyncReaderWriterInterface = template using ServerAsyncReaderWriter = ::grpc_impl::ServerAsyncReaderWriter; + +namespace internal { +template +using ClientAsyncReaderFactory = + ::grpc_impl::internal::ClientAsyncReaderFactory; + +template +using ClientAsyncWriterFactory = + ::grpc_impl::internal::ClientAsyncWriterFactory; + +template +using ClientAsyncReaderWriterFactory = + ::grpc_impl::internal::ClientAsyncReaderWriterFactory; + +} // namespace internal + } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h index 64ee17dec0d..cbbe70172c8 100644 --- a/include/grpcpp/impl/codegen/async_unary_call.h +++ b/include/grpcpp/impl/codegen/async_unary_call.h @@ -22,15 +22,25 @@ #include namespace grpc { + template using ClientAsyncResponseReaderInterface = grpc_impl::ClientAsyncResponseReaderInterface; + template using ClientAsyncResponseReader = grpc_impl::ClientAsyncResponseReader; template using ServerAsyncResponseWriter = ::grpc_impl::ServerAsyncResponseWriter; +namespace internal { + +template +using ClientAsyncResponseReaderFactory = + ::grpc_impl::internal::ClientAsyncResponseReaderFactory; + +} // namespace internal + } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 4f60741624a..9d183725b57 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -24,6 +24,18 @@ namespace grpc { namespace experimental { +template +using ClientCallbackReader = + ::grpc_impl::experimental::ClientCallbackReader; + +template +using ClientCallbackWriter = + ::grpc_impl::experimental::ClientCallbackWriter; + +template +using ClientCallbackReaderWriter = + ::grpc_impl::experimental::ClientCallbackReaderWriter; + template using ClientReadReactor = ::grpc_impl::experimental::ClientReadReactor; diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index cd447d7c5a5..852fe6676bf 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -22,36 +22,75 @@ #include namespace grpc { + +namespace internal { + +typedef ::grpc_impl::internal::ClientStreamingInterface + ClientStreamingInterface; + +typedef ::grpc_impl::internal::ServerStreamingInterface + ServerStreamingInterface; + +template +using ReaderInterface = ::grpc_impl::internal::ReaderInterface; + +template +using WriterInterface = ::grpc_impl::internal::WriterInterface; + +template +using ClientReaderFactory = ::grpc_impl::internal::ClientReaderFactory; + +template +using ClientWriterFactory = ::grpc_impl::internal::ClientWriterFactory; + +template +using ClientReaderWriterFactory = + ::grpc_impl::internal::ClientReaderWriterFactory; + +} // namespace internal + template using ClientReaderInterface = ::grpc_impl::ClientReaderInterface; template using ClientReader = ::grpc_impl::ClientReader; + template using ClientWriterInterface = ::grpc_impl::ClientWriterInterface; + template using ClientWriter = ::grpc_impl::ClientWriter; + template using ClientReaderWriterInterface = ::grpc_impl::ClientReaderWriterInterface; + template using ClientReaderWriter = ::grpc_impl::ClientReaderWriter; + template using ServerReaderInterface = ::grpc_impl::ServerReaderInterface; + template using ServerReader = ::grpc_impl::ServerReader; + template using ServerWriterInterface = ::grpc_impl::ServerWriterInterface; + template using ServerWriter = ::grpc_impl::ServerWriter; + template using ServerReaderWriterInterface = ::grpc_impl::ServerReaderWriterInterface; + template using ServerReaderWriter = ::grpc_impl::ServerReaderWriter; + template using ServerUnaryStreamer = ::grpc_impl::ServerUnaryStreamer; + template using ServerSplitStreamer = ::grpc_impl::ServerSplitStreamer; diff --git a/third_party/googletest b/third_party/googletest index 2fe3bd994b3..ec44c6c1675 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2 +Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780 diff --git a/third_party/protobuf b/third_party/protobuf index 09745575a92..582743bf40c 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 09745575a923640154bcf307fba8aedff47f240a +Subproject commit 582743bf40c5d3639a70f98f183914a2c0cd0680 From 5f55921b088b07af2348a894550874841a7a9b18 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 2 Jul 2019 12:37:08 -0700 Subject: [PATCH 561/676] Remove third_party --- third_party/googletest | 2 +- third_party/protobuf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/googletest b/third_party/googletest index ec44c6c1675..2fe3bd994b3 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit ec44c6c1675c25b9827aacd08c02433cccde7780 +Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2 diff --git a/third_party/protobuf b/third_party/protobuf index 582743bf40c..09745575a92 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 582743bf40c5d3639a70f98f183914a2c0cd0680 +Subproject commit 09745575a923640154bcf307fba8aedff47f240a From b1914bd46cab8a6f14788e4fa5ddd1fe45cd1ab5 Mon Sep 17 00:00:00 2001 From: mgravell Date: Tue, 2 Jul 2019 21:24:23 +0100 Subject: [PATCH 562/676] remove lazy usage --- src/csharp/Grpc.Core.Api/AuthProperty.cs | 7 ++----- src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/AuthProperty.cs b/src/csharp/Grpc.Core.Api/AuthProperty.cs index 0907edba84d..c208cee0267 100644 --- a/src/csharp/Grpc.Core.Api/AuthProperty.cs +++ b/src/csharp/Grpc.Core.Api/AuthProperty.cs @@ -17,8 +17,6 @@ #endregion using System; -using System.Collections.Generic; -using System.Linq; using System.Text; using Grpc.Core.Utils; @@ -33,13 +31,12 @@ namespace Grpc.Core static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; string name; byte[] valueBytes; - Lazy value; + string lazyValue; private AuthProperty(string name, byte[] valueBytes) { this.name = GrpcPreconditions.CheckNotNull(name); this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); - this.value = new Lazy(() => EncodingUTF8.GetString(this.valueBytes)); } /// @@ -60,7 +57,7 @@ namespace Grpc.Core { get { - return value.Value; + return lazyValue ?? (lazyValue = EncodingUTF8.GetString(this.valueBytes)); } } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index b33cb631e26..77e4ccd356d 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -38,7 +38,7 @@ namespace Grpc.Core private readonly Metadata responseTrailers; private Status status; private readonly IServerResponseStream serverResponseStream; - private readonly Lazy authContext; + private AuthContext lazyAuthContext; /// /// Creates a new instance of ServerCallContext. @@ -57,8 +57,6 @@ namespace Grpc.Core this.responseTrailers = new Metadata(); this.status = Status.DefaultSuccess; this.serverResponseStream = serverResponseStream; - // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object - this.authContext = new Lazy(GetAuthContextEager); } protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) @@ -97,7 +95,7 @@ namespace Grpc.Core set => serverResponseStream.WriteOptions = value; } - protected override AuthContext AuthContextCore => authContext.Value; + protected override AuthContext AuthContextCore => lazyAuthContext ?? (lazyAuthContext = GetAuthContextEager()); private AuthContext GetAuthContextEager() { From c9ce403dc46e494e8ae546c4e99e044dbdda5400 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 2 Jul 2019 14:00:46 -0700 Subject: [PATCH 563/676] Ensure bazel_hack terminates when running test_gevent. --- .../grpcio_tests/tests/bazel_namespace_package_hack.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index c6b72c327b1..0250dce0d61 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,9 +24,15 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" + print("Executing hack") + print("sys.path: {}".format(sys.path)) + items = [] for item in sys.path: + print("Checking {}".format(item)) if os.path.exists(item): # The only difference between sys.path and site-directory is # whether the .pth file will be parsed or not. A site-directory # will always exist in sys.path, but not another way around. - site.addsitedir(item) + items.append(item) + for item in items: + site.addsitedir(item) From 85b4e7948cecabb2b1ca5ebabb628ebc2a72a05e Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 2 Jul 2019 14:01:59 -0700 Subject: [PATCH 564/676] Remove debug prints --- src/python/grpcio_tests/tests/bazel_namespace_package_hack.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index 0250dce0d61..006a3deecb4 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,11 +24,8 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" - print("Executing hack") - print("sys.path: {}".format(sys.path)) items = [] for item in sys.path: - print("Checking {}".format(item)) if os.path.exists(item): # The only difference between sys.path and site-directory is # whether the .pth file will be parsed or not. A site-directory From 3bce424458ed4a3fefd191349dda1e672d8df5d0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Jul 2019 15:00:32 -0700 Subject: [PATCH 565/676] Remove debug code --- src/core/lib/gpr/sync_posix.cc | 129 ---------------------------- src/core/lib/iomgr/timer_manager.cc | 44 ---------- 2 files changed, 173 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index a30e36c11ac..fe2d5a9ca38 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -29,44 +29,6 @@ #include #include "src/core/lib/profiling/timers.h" -// For debug of the timer manager crash only. -// TODO (mxyan): remove after bug is fixed. -#ifdef GRPC_DEBUG_TIMER_MANAGER -#include -void (*g_grpc_debug_timer_manager_stats)( - int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, - int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, - int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, - int64_t abs_deadline_nsec_value, int64_t now1_sec_value, - int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, - int64_t add_result_sec_value, int64_t add_result_nsec_value, - int64_t sub_result_sec_value, int64_t sub_result_nsec_value, - int64_t next_value, int64_t start_time_sec, - int64_t start_time_nsec) = nullptr; -int64_t g_timer_manager_init_count = 0; -int64_t g_timer_manager_shutdown_count = 0; -int64_t g_fork_count = 0; -int64_t g_timer_wait_err = 0; -int64_t g_timer_cv_value = 0; -int64_t g_timer_mu_value = 0; -int64_t g_abstime_sec_value = -1; -int64_t g_abstime_nsec_value = -1; -int64_t g_abs_deadline_sec_value = -1; -int64_t g_abs_deadline_nsec_value = -1; -int64_t g_now1_sec_value = -1; -int64_t g_now1_nsec_value = -1; -int64_t g_now2_sec_value = -1; -int64_t g_now2_nsec_value = -1; -int64_t g_add_result_sec_value = -1; -int64_t g_add_result_nsec_value = -1; -int64_t g_sub_result_sec_value = -1; -int64_t g_sub_result_nsec_value = -1; -int64_t g_next_value = -1; -int64_t g_start_time_sec = -1; -int64_t g_start_time_nsec = -1; -#endif // GRPC_DEBUG_TIMER_MANAGER - #ifdef GPR_LOW_LEVEL_COUNTERS gpr_atm gpr_mu_locks = 0; gpr_atm gpr_counter_atm_cas = 0; @@ -152,63 +114,12 @@ void gpr_cv_destroy(gpr_cv* cv) { #endif } -// For debug of the timer manager crash only. -// TODO (mxyan): remove after bug is fixed. -#ifdef GRPC_DEBUG_TIMER_MANAGER -static gpr_timespec gpr_convert_clock_type_debug_timespec( - gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1, - gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) { - if (t.clock_type == clock_type) { - return t; - } - - if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) { - t.clock_type = clock_type; - return t; - } - - if (clock_type == GPR_TIMESPAN) { - return gpr_time_sub(t, gpr_now(t.clock_type)); - } - - if (t.clock_type == GPR_TIMESPAN) { - return gpr_time_add(gpr_now(clock_type), t); - } - - now1 = gpr_now(t.clock_type); - sub_result = gpr_time_sub(t, now1); - now2 = gpr_now(clock_type); - add_result = gpr_time_add(now2, sub_result); - return add_result; -} - -#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ - sub_result) \ - gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \ - (add_result), (sub_result)) -#else #define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ sub_result) \ gpr_convert_clock_type((t), (clock_type)) -#endif int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { int err = 0; -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - gpr_timespec abs_deadline_copy; - abs_deadline_copy.tv_sec = abs_deadline.tv_sec; - abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec; - gpr_timespec now1; - gpr_timespec now2; - gpr_timespec add_result; - gpr_timespec sub_result; - memset(&now1, 0, sizeof(now1)); - memset(&now2, 0, sizeof(now2)); - memset(&add_result, 0, sizeof(add_result)); - memset(&sub_result, 0, sizeof(sub_result)); -#endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { #ifdef GRPC_ASAN_ENABLED @@ -232,47 +143,7 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { #else err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); #endif - -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - if (GPR_UNLIKELY(!(err == 0 || err == ETIMEDOUT || err == EAGAIN))) { - g_abstime_sec_value = abs_deadline_ts.tv_sec; - g_abstime_nsec_value = abs_deadline_ts.tv_nsec; - } -#endif } - -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - if (GPR_UNLIKELY(!(err == 0 || err == ETIMEDOUT || err == EAGAIN))) { - if (g_grpc_debug_timer_manager_stats) { - g_timer_wait_err = err; - g_timer_cv_value = (int64_t)cv; - g_timer_mu_value = (int64_t)mu; - g_abs_deadline_sec_value = abs_deadline_copy.tv_sec; - g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec; - g_now1_sec_value = now1.tv_sec; - g_now1_nsec_value = now1.tv_nsec; - g_now2_sec_value = now2.tv_sec; - g_now2_nsec_value = now2.tv_nsec; - g_add_result_sec_value = add_result.tv_sec; - g_add_result_nsec_value = add_result.tv_nsec; - g_sub_result_sec_value = sub_result.tv_sec; - g_sub_result_nsec_value = sub_result.tv_nsec; - g_grpc_debug_timer_manager_stats( - g_timer_manager_init_count, g_timer_manager_shutdown_count, - g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, - g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value, - g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, - g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, - g_add_result_nsec_value, g_sub_result_sec_value, - g_sub_result_nsec_value, g_next_value, g_start_time_sec, - g_start_time_nsec); - } - } -#endif GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); return err == ETIMEDOUT; } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index bdf54909b4c..bb270af8129 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,30 +61,6 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); -// For debug of the timer manager crash only. -// TODO (mxyan): remove after bug is fixed. -#ifdef GRPC_DEBUG_TIMER_MANAGER -extern int64_t g_timer_manager_init_count; -extern int64_t g_timer_manager_shutdown_count; -extern int64_t g_fork_count; -extern int64_t g_next_value; -#endif // GRPC_DEBUG_TIMER_MANAGER - -static void gc_completed_threads(void) { - if (g_completed_threads != nullptr) { - completed_thread* to_gc = g_completed_threads; - g_completed_threads = nullptr; - gpr_mu_unlock(&g_mu); - while (to_gc != nullptr) { - to_gc->thd.Join(); - completed_thread* next = to_gc->next; - gpr_free(to_gc); - to_gc = next; - } - gpr_mu_lock(&g_mu); - } -} - static void start_timer_thread_and_unlock(void) { GPR_ASSERT(g_threaded); ++g_waiter_count; @@ -203,11 +179,6 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. -#ifdef GRPC_DEBUG_TIMER_MANAGER - g_next_value = next; -#endif gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); @@ -309,11 +280,6 @@ static void start_threads(void) { void grpc_timer_manager_init(void) { gpr_mu_init(&g_mu); gpr_cv_init(&g_cv_wait); -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - g_timer_manager_init_count++; -#endif gpr_cv_init(&g_cv_shutdown); g_threaded = false; g_thread_count = 0; @@ -349,11 +315,6 @@ static void stop_threads(void) { } void grpc_timer_manager_shutdown(void) { -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - g_timer_manager_shutdown_count++; -#endif stop_threads(); gpr_mu_destroy(&g_mu); @@ -362,11 +323,6 @@ void grpc_timer_manager_shutdown(void) { } void grpc_timer_manager_set_threading(bool threaded) { -#ifdef GRPC_DEBUG_TIMER_MANAGER - // For debug of the timer manager crash only. - // TODO (mxyan): remove after bug is fixed. - g_fork_count++; -#endif if (threaded) { start_threads(); } else { From 4be4df36247bd2ef540f235f930540e3c50a9530 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Tue, 25 Jun 2019 21:48:48 +0000 Subject: [PATCH 566/676] Bump min CMake to 3.5.1 to match Google benchmark The Google Benchmark CMake build needs CMake 3.5.1 or newer. CMake 3.5.1 was released May 24, 2016 and is available in Debian stable and Ubuntu 16.04 and 18.04. --- CMakeLists.txt | 2 +- examples/cpp/helloworld/CMakeLists.txt | 2 +- examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt | 2 +- templates/CMakeLists.txt.template | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a34f9265256..5780c91470f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) set(PACKAGE_NAME "grpc") set(PACKAGE_VERSION "1.23.0-dev") diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt index d0f705f6d99..146ee814261 100644 --- a/examples/cpp/helloworld/CMakeLists.txt +++ b/examples/cpp/helloworld/CMakeLists.txt @@ -17,7 +17,7 @@ # See cmake_externalproject/CMakeLists.txt for all-in-one cmake build # that automatically builds all the dependencies before building helloworld. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) project(HelloWorld C CXX) diff --git a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt index 9fbdf071a8d..0d8470a8d68 100644 --- a/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt +++ b/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt @@ -20,7 +20,7 @@ # including the "helloworld" project itself. # See https://blog.kitware.com/cmake-superbuilds-git-submodules/ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.5.1) # Project project(HelloWorld-SuperBuild C CXX) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 43bc063aee5..b9aa76fd6d6 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -69,7 +69,7 @@ return 'endif()\n' %> - cmake_minimum_required(VERSION 2.8) + cmake_minimum_required(VERSION 3.5.1) set(PACKAGE_NAME "grpc") set(PACKAGE_VERSION "${settings.cpp_version}") From 0a1f644da59a1f8598580d925e847c425e7a3786 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Jul 2019 16:44:47 -0700 Subject: [PATCH 567/676] Revert undesired deletion --- src/core/lib/iomgr/timer_manager.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index bb270af8129..04d4f881ecf 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,6 +61,21 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); +static void gc_completed_threads(void) { + if (g_completed_threads != nullptr) { + completed_thread* to_gc = g_completed_threads; + g_completed_threads = nullptr; + gpr_mu_unlock(&g_mu); + while (to_gc != nullptr) { + to_gc->thd.Join(); + completed_thread* next = to_gc->next; + gpr_free(to_gc); + to_gc = next; + } + gpr_mu_lock(&g_mu); + } +} + static void start_timer_thread_and_unlock(void) { GPR_ASSERT(g_threaded); ++g_waiter_count; From 42b7374880521652596e61818aef1bf8e936bf0b Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 2 Jul 2019 19:29:04 -0700 Subject: [PATCH 568/676] Force run --- src/core/lib/iomgr/executor/threadpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index 2ea1d5fcef4..3bc79aa6c3c 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -137,7 +137,7 @@ class ThreadPool : public ThreadPoolInterface { const char* thd_name_ = nullptr; Thread::Options thread_options_; ThreadPoolWorker** threads_ = nullptr; // Array of worker threads - MPMCQueueInterface* queue_ = nullptr; + MPMCQueueInterface* queue_ = nullptr; // Closure queue Atomic shut_down_{false}; // Destructor has been called if set to true From aaf5cf4cb7604030b3e5c8d81ec62d9dff2606ed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 3 Jul 2019 08:52:51 -0700 Subject: [PATCH 569/676] clang-format --- src/core/lib/iomgr/timer_manager.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 04d4f881ecf..17cae5cd4c3 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,20 +61,20 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); -static void gc_completed_threads(void) { - if (g_completed_threads != nullptr) { - completed_thread* to_gc = g_completed_threads; - g_completed_threads = nullptr; - gpr_mu_unlock(&g_mu); - while (to_gc != nullptr) { - to_gc->thd.Join(); - completed_thread* next = to_gc->next; - gpr_free(to_gc); - to_gc = next; - } - gpr_mu_lock(&g_mu); - } -} +static void gc_completed_threads(void) { + if (g_completed_threads != nullptr) { + completed_thread* to_gc = g_completed_threads; + g_completed_threads = nullptr; + gpr_mu_unlock(&g_mu); + while (to_gc != nullptr) { + to_gc->thd.Join(); + completed_thread* next = to_gc->next; + gpr_free(to_gc); + to_gc = next; + } + gpr_mu_lock(&g_mu); + } +} static void start_timer_thread_and_unlock(void) { GPR_ASSERT(g_threaded); From ad3957a48b53bd69e9a871f3a1aa49b15877975b Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Wed, 3 Jul 2019 11:47:18 -0700 Subject: [PATCH 570/676] Fix typo --- src/core/lib/iomgr/executor/mpmcqueue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index ea2a6868d2f..5eac7e29087 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -59,7 +59,7 @@ inline void* InfLenFIFOQueue::PopFront() { } Delete(head_to_remove); - // Singal waiting thread + // Signal waiting thread if (count_.Load(MemoryOrder::RELAXED) > 0 && num_waiters_ > 0) { wait_nonempty_.Signal(); } From af1b09f7e758d7aa61b3252151e0f9b20c564b09 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 26 Jun 2019 13:22:36 -0700 Subject: [PATCH 571/676] Enforce a Finite Time Gap Bound between Signal Receipt and Signal Handler Execution Previously, signal handlers were only given a chance to run upon receipt of an entry in the RPC stream. Since there is no time bound on how long that might take, there can be an arbitrarily long time gap between receipt of the signal and the execution of the application's signal handlers. Signal handlers are only run on the main thread. The cpython implementation takes great care to ensure that the main thread does not block for an arbitrarily long period between signal checks. Our indefinite blocking was due to wait() invocations on condition variables without a timeout. This changes all usages of wait() in the the channel implementation to use a wrapper that is responsive to signals even while waiting on an RPC. A test has been added to verify this. Tests are currently disabled under gevent due to https://github.com/grpc/grpc/issues/18980, but a fix for that has been found and should be merged shortly. --- src/python/grpcio/grpc/_channel.py | 151 ++++++++++------- src/python/grpcio/grpc/_common.py | 50 ++++++ src/python/grpcio_tests/commands.py | 2 + src/python/grpcio_tests/tests/tests.json | 1 + .../grpcio_tests/tests/unit/BUILD.bazel | 8 + .../grpcio_tests/tests/unit/_signal_client.py | 82 +++++++++ .../tests/unit/_signal_handling_test.py | 158 ++++++++++++++++++ 7 files changed, 393 insertions(+), 59 deletions(-) create mode 100644 src/python/grpcio_tests/tests/unit/_signal_client.py create mode 100644 src/python/grpcio_tests/tests/unit/_signal_handling_test.py diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 24f928ef69f..0bf8e03b5ce 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -13,6 +13,7 @@ # limitations under the License. """Invocation-side implementation of gRPC Python.""" +import functools import logging import sys import threading @@ -81,17 +82,6 @@ def _unknown_code_details(unknown_cygrpc_code, details): unknown_cygrpc_code, details) -def _wait_once_until(condition, until): - if until is None: - condition.wait() - else: - remaining = until - time.time() - if remaining < 0: - raise grpc.FutureTimeoutError() - else: - condition.wait(timeout=remaining) - - class _RPCState(object): def __init__(self, due, initial_metadata, trailing_metadata, code, details): @@ -178,12 +168,11 @@ def _event_handler(state, response_deserializer): #pylint: disable=too-many-statements def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): - if cygrpc.is_fork_support_enabled(): - condition_wait_timeout = 1.0 - else: - condition_wait_timeout = None + """Consume a request iterator supplied by the user.""" def consume_request_iterator(): # pylint: disable=too-many-branches + # Iterate over the request iterator until it is exhausted or an error + # condition is encountered. while True: return_from_user_request_generator_invoked = False try: @@ -224,14 +213,19 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, state.due.add(cygrpc.OperationType.send_message) else: return - while True: - state.condition.wait(condition_wait_timeout) - cygrpc.block_if_fork_in_progress(state) - if state.code is None: - if cygrpc.OperationType.send_message not in state.due: - break - else: - return + + def _done(): + return (state.code is not None or + cygrpc.OperationType.send_message not in + state.due) + + _common.wait( + state.condition.wait, + _done, + spin_cb=functools.partial( + cygrpc.block_if_fork_in_progress, state)) + if state.code is not None: + return else: return with state.condition: @@ -281,13 +275,21 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too with self._state.condition: return self._state.code is not None + def _is_complete(self): + return self._state.code is not None + def result(self, timeout=None): - until = None if timeout is None else time.time() + timeout + """Returns the result of the computation or raises its exception. + + See grpc.Future.result for the full API contract. + """ with self._state.condition: - while True: - if self._state.code is None: - _wait_once_until(self._state.condition, until) - elif self._state.code is grpc.StatusCode.OK: + timed_out = _common.wait( + self._state.condition.wait, self._is_complete, timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: return self._state.response elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -295,12 +297,17 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too raise self def exception(self, timeout=None): - until = None if timeout is None else time.time() + timeout + """Return the exception raised by the computation. + + See grpc.Future.exception for the full API contract. + """ with self._state.condition: - while True: - if self._state.code is None: - _wait_once_until(self._state.condition, until) - elif self._state.code is grpc.StatusCode.OK: + timed_out = _common.wait( + self._state.condition.wait, self._is_complete, timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: return None elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -308,12 +315,17 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too return self def traceback(self, timeout=None): - until = None if timeout is None else time.time() + timeout + """Access the traceback of the exception raised by the computation. + + See grpc.future.traceback for the full API contract. + """ with self._state.condition: - while True: - if self._state.code is None: - _wait_once_until(self._state.condition, until) - elif self._state.code is grpc.StatusCode.OK: + timed_out = _common.wait( + self._state.condition.wait, self._is_complete, timeout=timeout) + if timed_out: + raise grpc.FutureTimeoutError() + else: + if self._state.code is grpc.StatusCode.OK: return None elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -345,17 +357,23 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too raise StopIteration() else: raise self - while True: - self._state.condition.wait() - if self._state.response is not None: - response = self._state.response - self._state.response = None - return response - elif cygrpc.OperationType.receive_message not in self._state.due: - if self._state.code is grpc.StatusCode.OK: - raise StopIteration() - elif self._state.code is not None: - raise self + + def _response_ready(): + return ( + self._state.response is not None or + (cygrpc.OperationType.receive_message not in self._state.due + and self._state.code is not None)) + + _common.wait(self._state.condition.wait, _response_ready) + if self._state.response is not None: + response = self._state.response + self._state.response = None + return response + elif cygrpc.OperationType.receive_message not in self._state.due: + if self._state.code is grpc.StatusCode.OK: + raise StopIteration() + elif self._state.code is not None: + raise self def __iter__(self): return self @@ -386,32 +404,47 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too def initial_metadata(self): with self._state.condition: - while self._state.initial_metadata is None: - self._state.condition.wait() + + def _done(): + return self._state.initial_metadata is not None + + _common.wait(self._state.condition.wait, _done) return self._state.initial_metadata def trailing_metadata(self): with self._state.condition: - while self._state.trailing_metadata is None: - self._state.condition.wait() + + def _done(): + return self._state.trailing_metadata is not None + + _common.wait(self._state.condition.wait, _done) return self._state.trailing_metadata def code(self): with self._state.condition: - while self._state.code is None: - self._state.condition.wait() + + def _done(): + return self._state.code is not None + + _common.wait(self._state.condition.wait, _done) return self._state.code def details(self): with self._state.condition: - while self._state.details is None: - self._state.condition.wait() + + def _done(): + return self._state.details is not None + + _common.wait(self._state.condition.wait, _done) return _common.decode(self._state.details) def debug_error_string(self): with self._state.condition: - while self._state.debug_error_string is None: - self._state.condition.wait() + + def _done(): + return self._state.debug_error_string is not None + + _common.wait(self._state.condition.wait, _done) return _common.decode(self._state.debug_error_string) def _repr(self): diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index f69127e38ef..b4b24738e8f 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -15,6 +15,7 @@ import logging +import time import six import grpc @@ -60,6 +61,8 @@ STATUS_CODE_TO_CYGRPC_STATUS_CODE = { CYGRPC_STATUS_CODE_TO_STATUS_CODE) } +MAXIMUM_WAIT_TIMEOUT = 0.1 + def encode(s): if isinstance(s, bytes): @@ -96,3 +99,50 @@ def deserialize(serialized_message, deserializer): def fully_qualified_method(group, method): return '/{}/{}'.format(group, method) + + +def _wait_once(wait_fn, timeout, spin_cb): + wait_fn(timeout=timeout) + if spin_cb is not None: + spin_cb() + + +def wait(wait_fn, wait_complete_fn, timeout=None, spin_cb=None): + """Blocks waiting for an event without blocking the thread indefinitely. + + See https://github.com/grpc/grpc/issues/19464 for full context. CPython's + `threading.Event.wait` and `threading.Condition.wait` methods, if invoked + without a timeout kwarg, may block the calling thread indefinitely. If the + call is made from the main thread, this means that signal handlers may not + run for an arbitrarily long period of time. + + This wrapper calls the supplied wait function with an arbitrary short + timeout to ensure that no signal handler has to wait longer than + MAXIMUM_WAIT_TIMEOUT before executing. + + Args: + wait_fn: A callable acceptable a single float-valued kwarg named + `timeout`. This function is expected to be one of `threading.Event.wait` + or `threading.Condition.wait`. + wait_complete_fn: A callable taking no arguments and returning a bool. + When this function returns true, it indicates that waiting should cease. + timeout: An optional float-valued number of seconds after which the wait + should cease. + spin_cb: An optional Callable taking no arguments and returning nothing. + This callback will be called on each iteration of the spin. This may be + used for, e.g. work related to forking. + + Returns: + True if a timeout was supplied and it was reached. False otherwise. + """ + if timeout is None: + while not wait_complete_fn(): + _wait_once(wait_fn, MAXIMUM_WAIT_TIMEOUT, spin_cb) + else: + end = time.time() + timeout + while not wait_complete_fn(): + remaining = min(end - time.time(), MAXIMUM_WAIT_TIMEOUT) + if remaining < 0: + return True + _wait_once(wait_fn, remaining, spin_cb) + return False diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index dc0795d4a12..166cea101a4 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -145,6 +145,8 @@ class TestGevent(setuptools.Command): 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', + # TODO(https://github.com/grpc/grpc/issues/18980): Reenable. + 'unit._signal_handling_test.SignalHandlingTest', 'unit._metadata_flags_test', 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index cc08d56248a..16ba4847bc0 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -67,6 +67,7 @@ "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth", "unit._server_test.ServerTest", "unit._session_cache_test.SSLSessionCacheTest", + "unit._signal_handling_test.SignalHandlingTest", "unit._version_test.VersionTest", "unit.beta._beta_features_test.BetaFeaturesTest", "unit.beta._beta_features_test.ContextManagementAndLifecycleTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index a161794f8be..d21f5a59ad1 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -16,6 +16,7 @@ GRPCIO_TESTS_UNIT = [ "_credentials_test.py", "_dns_resolver_test.py", "_empty_message_test.py", + "_error_message_encoding_test.py", "_exit_test.py", "_interceptor_test.py", "_invalid_metadata_test.py", @@ -27,6 +28,7 @@ GRPCIO_TESTS_UNIT = [ # "_reconnect_test.py", "_resource_exhausted_test.py", "_rpc_test.py", + "_signal_handling_test.py", # TODO(ghostwriternr): To be added later. # "_server_ssl_cert_config_test.py", "_server_test.py", @@ -39,6 +41,11 @@ py_library( srcs = ["_tcp_proxy.py"], ) +py_library( + name = "_signal_client", + srcs = ["_signal_client.py"], +) + py_library( name = "resources", srcs = ["resources.py"], @@ -87,6 +94,7 @@ py_library( ":_server_shutdown_scenarios", ":_from_grpc_import_star", ":_tcp_proxy", + ":_signal_client", "//src/python/grpcio_tests/tests/unit/framework/common", "//src/python/grpcio_tests/tests/testing", requirement('six'), diff --git a/src/python/grpcio_tests/tests/unit/_signal_client.py b/src/python/grpcio_tests/tests/unit/_signal_client.py new file mode 100644 index 00000000000..da413db3b94 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_signal_client.py @@ -0,0 +1,82 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Client for testing responsiveness to signals.""" + +from __future__ import print_function + +import argparse +import functools +import logging +import signal +import sys + +import grpc + +SIGTERM_MESSAGE = "Handling sigterm!" + +UNARY_UNARY = "/test/Unary" +UNARY_STREAM = "/test/ServerStreaming" + +_MESSAGE = b'\x00\x00\x00' + +_ASSERTION_MESSAGE = "Control flow should never reach here." + +# NOTE(gnossen): We use a global variable here so that the signal handler can be +# installed before the RPC begins. If we do not do this, then we may receive the +# SIGINT before the signal handler is installed. I'm not happy with per-process +# global state, but the per-process global state that is signal handlers +# somewhat forces my hand. +per_process_rpc_future = None + + +def handle_sigint(unused_signum, unused_frame): + print(SIGTERM_MESSAGE) + if per_process_rpc_future is not None: + per_process_rpc_future.cancel() + sys.stderr.flush() + sys.exit(0) + + +def main_unary(server_target): + global per_process_rpc_future # pylint: disable=global-statement + with grpc.insecure_channel(server_target) as channel: + multicallable = channel.unary_unary(UNARY_UNARY) + signal.signal(signal.SIGINT, handle_sigint) + per_process_rpc_future = multicallable.future( + _MESSAGE, wait_for_ready=True) + result = per_process_rpc_future.result() + assert False, _ASSERTION_MESSAGE + + +def main_streaming(server_target): + global per_process_rpc_future # pylint: disable=global-statement + with grpc.insecure_channel(server_target) as channel: + signal.signal(signal.SIGINT, handle_sigint) + per_process_rpc_future = channel.unary_stream(UNARY_STREAM)( + _MESSAGE, wait_for_ready=True) + for result in per_process_rpc_future: + pass + assert False, _ASSERTION_MESSAGE + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Signal test client.') + parser.add_argument('server', help='Server target') + parser.add_argument( + 'arity', help='RPC arity', choices=('unary', 'streaming')) + args = parser.parse_args() + if args.arity == 'unary': + main_unary(args.server) + else: + main_streaming(args.server) diff --git a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py new file mode 100644 index 00000000000..9d0d64709af --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py @@ -0,0 +1,158 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test of responsiveness to signals.""" + +from __future__ import print_function + +import logging +import os +import signal +import subprocess +import tempfile +import threading +import unittest +import sys + +import grpc + +from tests.unit import test_common +from tests.unit import _signal_client + +_CLIENT_PATH = os.path.abspath(os.path.realpath(_signal_client.__file__)) +_HOST = 'localhost' + + +class _GenericHandler(grpc.GenericRpcHandler): + + def __init__(self): + self._connected_clients_lock = threading.RLock() + self._connected_clients_event = threading.Event() + self._connected_clients = 0 + + self._unary_unary_handler = grpc.unary_unary_rpc_method_handler( + self._handle_unary_unary) + self._unary_stream_handler = grpc.unary_stream_rpc_method_handler( + self._handle_unary_stream) + + def _on_client_connect(self): + with self._connected_clients_lock: + self._connected_clients += 1 + self._connected_clients_event.set() + + def _on_client_disconnect(self): + with self._connected_clients_lock: + self._connected_clients -= 1 + if self._connected_clients == 0: + self._connected_clients_event.clear() + + def await_connected_client(self): + """Blocks until a client connects to the server.""" + self._connected_clients_event.wait() + + def _handle_unary_unary(self, request, servicer_context): + """Handles a unary RPC. + + Blocks until the client disconnects and then echoes. + """ + stop_event = threading.Event() + + def on_rpc_end(): + self._on_client_disconnect() + stop_event.set() + + servicer_context.add_callback(on_rpc_end) + self._on_client_connect() + stop_event.wait() + return request + + def _handle_unary_stream(self, request, servicer_context): + """Handles a server streaming RPC. + + Blocks until the client disconnects and then echoes. + """ + stop_event = threading.Event() + + def on_rpc_end(): + self._on_client_disconnect() + stop_event.set() + + servicer_context.add_callback(on_rpc_end) + self._on_client_connect() + stop_event.wait() + yield request + + def service(self, handler_call_details): + if handler_call_details.method == _signal_client.UNARY_UNARY: + return self._unary_unary_handler + elif handler_call_details.method == _signal_client.UNARY_STREAM: + return self._unary_stream_handler + else: + return None + + +def _read_stream(stream): + stream.seek(0) + return stream.read() + + +class SignalHandlingTest(unittest.TestCase): + + def setUp(self): + self._server = test_common.test_server() + self._port = self._server.add_insecure_port('{}:0'.format(_HOST)) + self._handler = _GenericHandler() + self._server.add_generic_rpc_handlers((self._handler,)) + self._server.start() + + def tearDown(self): + self._server.stop(None) + + @unittest.skipIf(os.name == 'nt', 'SIGINT not supported on windows') + def testUnary(self): + """Tests that the server unary code path does not stall signal handlers.""" + server_target = '{}:{}'.format(_HOST, self._port) + with tempfile.TemporaryFile(mode='r') as client_stdout: + with tempfile.TemporaryFile(mode='r') as client_stderr: + client = subprocess.Popen( + (sys.executable, _CLIENT_PATH, server_target, 'unary'), + stdout=client_stdout, + stderr=client_stderr) + self._handler.await_connected_client() + client.send_signal(signal.SIGINT) + self.assertFalse(client.wait(), msg=_read_stream(client_stderr)) + client_stdout.seek(0) + self.assertIn(_signal_client.SIGTERM_MESSAGE, + client_stdout.read()) + + @unittest.skipIf(os.name == 'nt', 'SIGINT not supported on windows') + def testStreaming(self): + """Tests that the server streaming code path does not stall signal handlers.""" + server_target = '{}:{}'.format(_HOST, self._port) + with tempfile.TemporaryFile(mode='r') as client_stdout: + with tempfile.TemporaryFile(mode='r') as client_stderr: + client = subprocess.Popen( + (sys.executable, _CLIENT_PATH, server_target, 'streaming'), + stdout=client_stdout, + stderr=client_stderr) + self._handler.await_connected_client() + client.send_signal(signal.SIGINT) + self.assertFalse(client.wait(), msg=_read_stream(client_stderr)) + client_stdout.seek(0) + self.assertIn(_signal_client.SIGTERM_MESSAGE, + client_stdout.read()) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) From f7182fe4f2f3b4fe91885b20fd91ff9a4f3ecf3a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 14:32:01 -0700 Subject: [PATCH 572/676] Add explanation to _signal_client --- src/python/grpcio_tests/tests/unit/_signal_client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_signal_client.py b/src/python/grpcio_tests/tests/unit/_signal_client.py index da413db3b94..65ddd6d858e 100644 --- a/src/python/grpcio_tests/tests/unit/_signal_client.py +++ b/src/python/grpcio_tests/tests/unit/_signal_client.py @@ -49,6 +49,7 @@ def handle_sigint(unused_signum, unused_frame): def main_unary(server_target): + """Initiate a unary RPC to be interrupted by a SIGINT.""" global per_process_rpc_future # pylint: disable=global-statement with grpc.insecure_channel(server_target) as channel: multicallable = channel.unary_unary(UNARY_UNARY) @@ -60,6 +61,7 @@ def main_unary(server_target): def main_streaming(server_target): + """Initiate a streaming RPC to be interrupted by a SIGINT.""" global per_process_rpc_future # pylint: disable=global-statement with grpc.insecure_channel(server_target) as channel: signal.signal(signal.SIGINT, handle_sigint) From b41ded289e12e7fc96222fd1dbd7a508c164aac1 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 12:35:12 -0700 Subject: [PATCH 573/676] WIP. Check for NULL --- src/core/lib/iomgr/fork_posix.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 629b08162fb..444d2574c7e 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -59,8 +59,9 @@ void grpc_prefork() { "environment variable GRPC_ENABLE_FORK_SUPPORT=1"); return; } - if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 && - strcmp(grpc_get_poll_strategy_name(), "poll") != 0) { + const char * poll_strategy_name = grpc_get_poll_strategy_name(); + if (poll_strategy_name == nullptr || strcmp(poll_strategy_name, "epoll1") != 0 && + strcmp(poll_strategy_name, "poll") != 0) { gpr_log(GPR_INFO, "Fork support is only compatible with the epoll1 and poll polling " "strategies"); From 5e35a367d94a2b37897a256737dd1bd73658eb2f Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 3 Jul 2019 18:52:29 -0400 Subject: [PATCH 574/676] Revert "Clearly callout the behavior for listening ports." --- include/grpcpp/server_builder_impl.h | 4 ---- src/core/lib/gprpp/host_port.cc | 23 ++++++++++++++++++----- test/core/gprpp/host_port_test.cc | 2 ++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 9c69adc9147..7f85e807d07 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -112,10 +112,6 @@ class ServerBuilder { /// /// It can be invoked multiple times. /// - /// If port is not provided in the \a addr (e.g., "1.2.3.4:" or "1.2.3.4"), - /// the default port (i.e., https) is used. To request an ephemeral port, - /// \a addr must include 0 as the port number (e.g., "1.2.3.4:0"). - /// /// \param addr_uri The address to try to bind to the server in URI form. If /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 diff --git a/src/core/lib/gprpp/host_port.cc b/src/core/lib/gprpp/host_port.cc index 13b63eb902b..e7f0e4461e9 100644 --- a/src/core/lib/gprpp/host_port.cc +++ b/src/core/lib/gprpp/host_port.cc @@ -44,7 +44,10 @@ int JoinHostPort(UniquePtr* out, const char* host, int port) { return ret; } -bool SplitHostPort(StringView name, StringView* host, StringView* port) { +namespace { +bool DoSplitHostPort(StringView name, StringView* host, StringView* port, + bool* has_port) { + *has_port = false; if (name[0] == '[') { /* Parse a bracketed host, typically an IPv6 literal. */ const size_t rbracket = name.find(']', 1); @@ -58,6 +61,7 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { } else if (name[rbracket + 1] == ':') { /* ]: */ *port = name.substr(rbracket + 2, name.size() - rbracket - 2); + *has_port = true; } else { /* ] */ return false; @@ -76,6 +80,7 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { /* Exactly 1 colon. Split into host:port. */ *host = name.substr(0, colon); *port = name.substr(colon + 1, name.size() - colon - 1); + *has_port = true; } else { /* 0 or 2+ colons. Bare hostname or IPv6 litearal. */ *host = name; @@ -84,6 +89,12 @@ bool SplitHostPort(StringView name, StringView* host, StringView* port) { } return true; } +} // namespace + +bool SplitHostPort(StringView name, StringView* host, StringView* port) { + bool unused; + return DoSplitHostPort(name, host, port, &unused); +} bool SplitHostPort(StringView name, UniquePtr* host, UniquePtr* port) { @@ -91,12 +102,14 @@ bool SplitHostPort(StringView name, UniquePtr* host, GPR_DEBUG_ASSERT(port != nullptr && *port == nullptr); StringView host_view; StringView port_view; - const bool ret = SplitHostPort(name, &host_view, &port_view); + bool has_port; + const bool ret = DoSplitHostPort(name, &host_view, &port_view, &has_port); if (ret) { - // We always set the host, but port is set only when it's non-empty, - // to remain backward compatible with the old split_host_port API. + // We always set the host, but port is set only when DoSplitHostPort find a + // port in the string, to remain backward compatible with the old + // gpr_split_host_port API. *host = host_view.dup(); - if (!port_view.empty()) { + if (has_port) { *port = port_view.dup(); } } diff --git a/test/core/gprpp/host_port_test.cc b/test/core/gprpp/host_port_test.cc index 3b392da66e8..cfe0eddb036 100644 --- a/test/core/gprpp/host_port_test.cc +++ b/test/core/gprpp/host_port_test.cc @@ -71,7 +71,9 @@ static void test_split_host_port() { split_host_port_expect("", "", nullptr, true); split_host_port_expect("[a:b]", "a:b", nullptr, true); split_host_port_expect("1.2.3.4", "1.2.3.4", nullptr, true); + split_host_port_expect("0.0.0.0:", "0.0.0.0", "", true); split_host_port_expect("a:b:c::", "a:b:c::", nullptr, true); + split_host_port_expect("[a:b:c::]:", "a:b:c::", "", true); split_host_port_expect("[a:b]:30", "a:b", "30", true); split_host_port_expect("1.2.3.4:30", "1.2.3.4", "30", true); split_host_port_expect(":30", "", "30", true); From eab6f7a64b31226f73535bca97ca14c1c14b421c Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 16:02:29 -0700 Subject: [PATCH 575/676] Clang format --- src/core/lib/iomgr/fork_posix.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 444d2574c7e..248e9ae5f54 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -59,9 +59,10 @@ void grpc_prefork() { "environment variable GRPC_ENABLE_FORK_SUPPORT=1"); return; } - const char * poll_strategy_name = grpc_get_poll_strategy_name(); - if (poll_strategy_name == nullptr || strcmp(poll_strategy_name, "epoll1") != 0 && - strcmp(poll_strategy_name, "poll") != 0) { + const char* poll_strategy_name = grpc_get_poll_strategy_name(); + if (poll_strategy_name == nullptr || + strcmp(poll_strategy_name, "epoll1") != 0 && + strcmp(poll_strategy_name, "poll") != 0) { gpr_log(GPR_INFO, "Fork support is only compatible with the epoll1 and poll polling " "strategies"); From dd22893c322dcd7c4425d5a2aba26789fa4fbc23 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 16:03:23 -0700 Subject: [PATCH 576/676] Clarify API contract for grpc_get_poll_strategy_name --- src/core/lib/iomgr/ev_posix.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index d78ac2dac2d..02e4da1c349 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -206,7 +206,8 @@ void grpc_register_event_engine_factory(const char* name, GPR_ASSERT(false); } -/* Call this only after calling grpc_event_engine_init() */ +/*If grpc_event_engine_init() has been called, returns the poll_strategy_name. + * Otherwise, returns nullptr. */ const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; } void grpc_event_engine_init(void) { From 5087ab48bf5377c2dc89fe7b28b5dbbefab5889c Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 16:22:40 -0700 Subject: [PATCH 577/676] Reenable signal handling test --- src/python/grpcio_tests/commands.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 166cea101a4..dc0795d4a12 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -145,8 +145,6 @@ class TestGevent(setuptools.Command): 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', - # TODO(https://github.com/grpc/grpc/issues/18980): Reenable. - 'unit._signal_handling_test.SignalHandlingTest', 'unit._metadata_flags_test', 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests From 6bcd74e903ac2e5491026e550dfcc744be27a411 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 3 Jul 2019 16:58:38 -0700 Subject: [PATCH 578/676] Add parentheses --- src/core/lib/iomgr/fork_posix.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 248e9ae5f54..e678b4f5905 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -61,8 +61,8 @@ void grpc_prefork() { } const char* poll_strategy_name = grpc_get_poll_strategy_name(); if (poll_strategy_name == nullptr || - strcmp(poll_strategy_name, "epoll1") != 0 && - strcmp(poll_strategy_name, "poll") != 0) { + (strcmp(poll_strategy_name, "epoll1") != 0 && + strcmp(poll_strategy_name, "poll") != 0)) { gpr_log(GPR_INFO, "Fork support is only compatible with the epoll1 and poll polling " "strategies"); From b0b81792ee4d12a68a3382b8a008217706c55617 Mon Sep 17 00:00:00 2001 From: yunjiaw26 <50971092+yunjiaw26@users.noreply.github.com> Date: Wed, 3 Jul 2019 18:00:14 -0700 Subject: [PATCH 579/676] Delete bm_threadpool.cc --- test/cpp/microbenchmarks/bm_threadpool.cc | 327 ---------------------- 1 file changed, 327 deletions(-) delete mode 100644 test/cpp/microbenchmarks/bm_threadpool.cc diff --git a/test/cpp/microbenchmarks/bm_threadpool.cc b/test/cpp/microbenchmarks/bm_threadpool.cc deleted file mode 100644 index 601108aacab..00000000000 --- a/test/cpp/microbenchmarks/bm_threadpool.cc +++ /dev/null @@ -1,327 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/iomgr/executor/threadpool.h" - -#include - -#include - -#include "test/cpp/microbenchmarks/helpers.h" -#include "test/cpp/util/test_config.h" - -namespace grpc { -namespace testing { - -// This helper class allows a thread to block for s pre-specified number of -// actions. BlockingCounter has a initial non-negative count on initialization -// Each call to DecrementCount will decrease the count by 1. When making a call -// to Wait, if the count is greater than 0, the thread will be block, until -// the count reaches 0, it will unblock. -class BlockingCounter { - public: - BlockingCounter(int count) : count_(count) {} - void DecrementCount() { - std::lock_guard l(mu_); - count_--; - cv_.notify_one(); - } - - void Wait() { - std::unique_lock l(mu_); - while (count_ > 0) { - cv_.wait(l); - } - } - - private: - int count_; - std::mutex mu_; - std::condition_variable cv_; -}; - -// This is a functor/closure class for threadpool microbenchmark. -// This functor (closure) class will add another functor into pool if the -// number passed in (num_add) is greater than 0. Otherwise, it will decrement -// the counter to indicate that task is finished. This functor will suicide at -// the end, therefore, no need for caller to do clean-ups. -class AddAnotherFunctor : public grpc_experimental_completion_queue_functor { - public: - AddAnotherFunctor(grpc_core::ThreadPool* pool, BlockingCounter* counter, - int num_add) - : pool_(pool), counter_(counter), num_add_(num_add) { - functor_run = &AddAnotherFunctor::Run; - internal_next = this; - internal_success = 0; - } - ~AddAnotherFunctor() {} - // When the functor gets to run in thread pool, it will take internal_next - // as first argument and internal_success as second one. Therefore, the - // first argument here would be the closure itself. - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - auto* callback = static_cast(cb); - if (--callback->num_add_ > 0) { - callback->pool_->Add(new AddAnotherFunctor( - callback->pool_, callback->counter_, callback->num_add_)); - } else { - callback->counter_->DecrementCount(); - } - // Suicide - delete callback; - } - - private: - grpc_core::ThreadPool* pool_; - BlockingCounter* counter_; - int num_add_; -}; - -void ThreadPoolAddAnotherHelper(benchmark::State& state, - int concurrent_functor) { - const int num_threads = state.range(0); - const int num_iterations = state.range(1); - // number of adds done by each closure - const int num_add = num_iterations / concurrent_functor; - grpc_core::ThreadPool pool(num_threads); - while (state.KeepRunningBatch(num_iterations)) { - BlockingCounter* counter = new BlockingCounter(concurrent_functor); - for (int i = 0; i < concurrent_functor; ++i) { - pool.Add(new AddAnotherFunctor(&pool, counter, num_add)); - } - counter->Wait(); - delete counter; - } - state.SetItemsProcessed(state.iterations()); -} - -// This benchmark will let a closure add a new closure into pool. Concurrent -// closures range from 1 to 2048 -static void BM_ThreadPool1AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 1); -} -BENCHMARK(BM_ThreadPool1AddAnother) - ->UseRealTime() - // First pair is range for number of threads in pool, second pair is range - // for number of iterations - ->Ranges({{1, 1024}, {524288, 2097152}}); // 512K ~ 2M - -static void BM_ThreadPool4AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 4); -} -BENCHMARK(BM_ThreadPool4AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 2097152}}); - -static void BM_ThreadPool8AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 8); -} -BENCHMARK(BM_ThreadPool8AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); // 512K ~ 1M - -static void BM_ThreadPool16AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 16); -} -BENCHMARK(BM_ThreadPool16AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -static void BM_ThreadPool32AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 32); -} -BENCHMARK(BM_ThreadPool32AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -static void BM_ThreadPool64AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 64); -} -BENCHMARK(BM_ThreadPool64AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -static void BM_ThreadPool128AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 128); -} -BENCHMARK(BM_ThreadPool128AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -static void BM_ThreadPool512AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 512); -} -BENCHMARK(BM_ThreadPool512AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -static void BM_ThreadPool2048AddAnother(benchmark::State& state) { - ThreadPoolAddAnotherHelper(state, 2048); -} -BENCHMARK(BM_ThreadPool2048AddAnother) - ->UseRealTime() - ->Ranges({{1, 1024}, {524288, 1048576}}); - -// A functor class that will delete self on end of running. -class SuicideFunctorForAdd : public grpc_experimental_completion_queue_functor { - public: - SuicideFunctorForAdd() { - functor_run = &SuicideFunctorForAdd::Run; - internal_next = this; - internal_success = 0; - } - ~SuicideFunctorForAdd() {} - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - // On running, the first argument would be internal_next, which is itself. - delete cb; - } -}; - -// Performs the scenario of external thread(s) adding closures into pool. -static void BM_ThreadPoolExternalAdd(benchmark::State& state) { - const int num_threads = state.range(0); - static grpc_core::ThreadPool* pool = - grpc_core::New(num_threads); - for (auto _ : state) { - pool->Add(new SuicideFunctorForAdd()); - } - state.SetItemsProcessed(state.iterations()); -} -BENCHMARK(BM_ThreadPoolExternalAdd) - ->Range(1, 1024) - ->ThreadRange(1, 1024) // concurrent external thread(s) up to 1024 - ->UseRealTime(); - -// Functor (closure) that adds itself into pool repeatedly. By adding self, the -// overhead would be low and can measure the time of add more accurately. -class AddSelfFunctor : public grpc_experimental_completion_queue_functor { - public: - AddSelfFunctor(grpc_core::ThreadPool* pool, BlockingCounter* counter, - int num_add) - : pool_(pool), counter_(counter), num_add_(num_add) { - functor_run = &AddSelfFunctor::Run; - internal_next = this; - internal_success = 0; - } - ~AddSelfFunctor() {} - // When the functor gets to run in thread pool, it will take internal_next - // as first argument and internal_success as second one. Therefore, the - // first argument here would be the closure itself. - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - auto* callback = static_cast(cb); - if (--callback->num_add_ > 0) { - callback->pool_->Add(cb); - } else { - callback->counter_->DecrementCount(); - // Suicide - delete callback; - } - } - - private: - grpc_core::ThreadPool* pool_; - BlockingCounter* counter_; - int num_add_; -}; - -static void BM_ThreadPoolAddSelf(benchmark::State& state) { - const int num_threads = state.range(0); - const int kNumIteration = 524288; - int concurrent_functor = num_threads; - int num_add = kNumIteration / concurrent_functor; - grpc_core::ThreadPool pool(num_threads); - while (state.KeepRunningBatch(kNumIteration)) { - BlockingCounter* counter = new BlockingCounter(concurrent_functor); - for (int i = 0; i < concurrent_functor; ++i) { - pool.Add(new AddSelfFunctor(&pool, counter, num_add)); - } - counter->Wait(); - delete counter; - } - state.SetItemsProcessed(state.iterations()); -} - -BENCHMARK(BM_ThreadPoolAddSelf)->UseRealTime()->Range(1, 1024); - -// A functor (closure) that simulates closures with small but non-trivial amount -// of work. -class ShortWorkFunctorForAdd - : public grpc_experimental_completion_queue_functor { - public: - BlockingCounter* counter_; - - ShortWorkFunctorForAdd() { - functor_run = &ShortWorkFunctorForAdd::Run; - internal_next = this; - internal_success = 0; - val_ = 0; - } - ~ShortWorkFunctorForAdd() {} - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - auto* callback = static_cast(cb); - for (int i = 0; i < 1000; ++i) { - callback->val_++; - } - callback->counter_->DecrementCount(); - } - - private: - int val_; -}; - -// Simulates workloads where many short running callbacks are added to the -// threadpool. The callbacks are not enough to keep all the workers busy -// continuously so the number of workers running changes overtime. -// -// In effect this tests how well the threadpool avoids spurious wakeups. -static void BM_SpikyLoad(benchmark::State& state) { - const int num_threads = state.range(0); - - const int kNumSpikes = 1000; - const int batch_size = 3 * num_threads; - std::vector work_vector(batch_size); - while (state.KeepRunningBatch(kNumSpikes * batch_size)) { - grpc_core::ThreadPool pool(num_threads); - for (int i = 0; i != kNumSpikes; ++i) { - BlockingCounter counter(batch_size); - for (auto& w : work_vector) { - w.counter_ = &counter; - pool.Add(&w); - } - counter.Wait(); - } - } - state.SetItemsProcessed(state.iterations() * batch_size); -} -BENCHMARK(BM_SpikyLoad)->Arg(1)->Arg(2)->Arg(4)->Arg(8)->Arg(16); - -} // namespace testing -} // namespace grpc - -// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, -// and others do not. This allows us to support both modes. -namespace benchmark { -void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } -} // namespace benchmark - -int main(int argc, char** argv) { - LibraryInitializer libInit; - ::benchmark::Initialize(&argc, argv); - ::grpc::testing::InitTest(&argc, &argv, false); - benchmark::RunTheBenchmarksNamespaced(); - return 0; -} From fdc250d6189b636ecfda7b2314662e62a9bbe868 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 3 Jul 2019 18:23:12 -0700 Subject: [PATCH 580/676] remove bencharmk --- test/cpp/microbenchmarks/BUILD | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 576eab554a4..d9424f24f16 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -214,14 +214,6 @@ grpc_cc_binary( ], ) -grpc_cc_binary( - name = "bm_threadpool", - testonly = 1, - srcs = ["bm_threadpool.cc"], - tags = ["no_windows"], - deps = [":helpers"], -) - grpc_cc_binary( name = "bm_timer", testonly = 1, From b6e104f22f6baec437828014611a196f4cf72c4b Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 08:21:17 +0100 Subject: [PATCH 581/676] make use of Encoding.GetString(byte*, int) when available; poly-fill when not available (NET45); move related logic to extension class --- src/csharp/Grpc.Core.Api/Metadata.cs | 17 ++------- .../Grpc.Core.Api/Utils/EncodingExtensions.cs | 36 +++++++++++++++++++ src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 23 ++++-------- 3 files changed, 45 insertions(+), 31 deletions(-) create mode 100644 src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs diff --git a/src/csharp/Grpc.Core.Api/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs index 7a04a2ee859..cd1ea3b4676 100644 --- a/src/csharp/Grpc.Core.Api/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -19,7 +19,7 @@ using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; -using System.Text.RegularExpressions; +using Grpc.Core.Api.Utils; using Grpc.Core.Utils; @@ -364,20 +364,7 @@ namespace Grpc.Core } else { - string s; - if (length == 0) - { - s = ""; - } - else - { - int charCount = EncodingASCII.GetCharCount(source, length); - s = new string('\0', charCount); - fixed (char* cPtr = s) - { - EncodingASCII.GetChars(source, length, cPtr, charCount); - } - } + string s = length == 0 ? "" : EncodingASCII.GetString(source, length); return new Entry(key, s, null); } } diff --git a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs new file mode 100644 index 00000000000..ef38baf5cc4 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs @@ -0,0 +1,36 @@ +using System; +using System.Text; + +namespace Grpc.Core.Api.Utils +{ + + internal static class EncodingExtensions + { +#if NET45 // back-fill over a method missing in NET45 + /// + /// Converts byte* pointing to an encoded byte array to a string using the provided Encoding. + /// + public static unsafe string GetString(this Encoding encoding, byte* source, int byteCount) + { + if (byteCount == 0) return ""; // most callers will have already checked, but: make sure + + // allocate a right-sized string and decode into it + int charCount = encoding.GetCharCount(source, byteCount); + string s = new string('\0', charCount); + fixed (char* cPtr = s) + { + encoding.GetChars(source, byteCount, cPtr, charCount); + } + return s; + } +#endif + /// + /// Converts IntPtr pointing to a encoded byte array to a string using the provided Encoding. + /// + public static unsafe string GetString(this Encoding encoding, IntPtr ptr, int len) + { + return len == 0 ? "" : encoding.GetString((byte*)ptr.ToPointer(), len); + } + } + +} diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 54b4370935d..313e2b5c9d7 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -17,8 +17,9 @@ #endregion using System; -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; using System.Text; +using Grpc.Core.Api.Utils; namespace Grpc.Core.Internal { @@ -32,22 +33,10 @@ namespace Grpc.Core.Internal /// /// Converts IntPtr pointing to a UTF-8 encoded byte array to string. /// - public static unsafe string PtrToStringUTF8(IntPtr ptr, int len) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string PtrToStringUTF8(IntPtr ptr, int len) { - if (len == 0) - { - return ""; - } - - // allocate a right-sized string and decode into it - byte* source = (byte*)ptr.ToPointer(); - int charCount = EncodingUTF8.GetCharCount(source, len); - string s = new string('\0', charCount); - fixed(char* cPtr = s) - { - EncodingUTF8.GetChars(source, len, cPtr, charCount); - } - return s; + return EncodingUTF8.GetString(ptr, len); } /// @@ -66,6 +55,7 @@ namespace Grpc.Core.Internal /// /// Returns the maximum number of bytes required to encode a given string. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMaxByteCountUTF8(string str) { return EncodingUTF8.GetMaxByteCount(str.Length); @@ -74,6 +64,7 @@ namespace Grpc.Core.Internal /// /// Returns the actual number of bytes required to encode a given string. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetByteCountUTF8(string str) { return EncodingUTF8.GetByteCount(str); From b3528734616b49055c9f6ae2d647cf8423462ac2 Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 08:30:51 +0100 Subject: [PATCH 582/676] UTF encode/native: use IntPtr, not byte*, in the native API (avoid "unsafe" declaration) --- .../Grpc.Core/Internal/CallSafeHandle.cs | 53 ++++++++++--------- .../Internal/NativeMethods.Generated.cs | 6 +-- src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs | 13 ++--- .../Grpc.Core/Internal/native_methods.include | 4 +- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index c62297b0972..2e637c9704b 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -128,7 +128,7 @@ namespace Grpc.Core.Internal } } - public unsafe void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, + public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags) { using (completionQueue.NewScope()) @@ -146,32 +146,35 @@ namespace Grpc.Core.Internal maxBytes = MarshalUtils.GetByteCountUTF8(status.Detail); } - if (maxBytes <= MaxStackAllocBytes) - { // for small status, we can encode on the stack without touching arrays - // note: if init-locals is disabled, it would be more efficient - // to just stackalloc[MaxStackAllocBytes]; but by default, since we - // expect this to be small and it needs to wipe, just use maxBytes - byte* ptr = stackalloc byte[maxBytes]; - int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); - Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, ptr, new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, - optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); - } - else - { // for larger status (rare), rent a buffer from the pool and - // use that for encoding - var statusBuffer = ArrayPool.Shared.Rent(maxBytes); - try - { - fixed (byte* ptr = statusBuffer) + unsafe + { + if (maxBytes <= MaxStackAllocBytes) + { // for small status, we can encode on the stack without touching arrays + // note: if init-locals is disabled, it would be more efficient + // to just stackalloc[MaxStackAllocBytes]; but by default, since we + // expect this to be small and it needs to wipe, just use maxBytes + byte* ptr = stackalloc byte[maxBytes]; + int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); + Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, new IntPtr(ptr), new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, + optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + } + else + { // for larger status (rare), rent a buffer from the pool and + // use that for encoding + var statusBuffer = ArrayPool.Shared.Rent(maxBytes); + try { - int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); - Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, ptr, new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, - optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + fixed (byte* ptr = statusBuffer) + { + int statusBytes = MarshalUtils.GetBytesUTF8(status.Detail, ptr, maxBytes); + Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, new IntPtr(ptr), new UIntPtr((ulong)statusBytes), metadataArray, sendEmptyInitialMetadata ? 1 : 0, + optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); + } + } + finally + { + ArrayPool.Shared.Return(statusBuffer); } - } - finally - { - ArrayPool.Shared.Return(statusBuffer); } } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index e67263edbda..d98f0226e3f 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -475,7 +475,7 @@ namespace Grpc.Core.Internal public delegate CallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags); public delegate CallError grpcsharp_call_send_message_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata); public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); - public unsafe delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, IntPtr statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); public delegate CallError grpcsharp_call_recv_message_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); public delegate CallError grpcsharp_call_recv_initial_metadata_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); public delegate CallError grpcsharp_call_start_serverside_delegate(CallSafeHandle call, BatchContextSafeHandle ctx); @@ -643,7 +643,7 @@ namespace Grpc.Core.Internal public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static unsafe extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, IntPtr statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); [DllImport(ImportName)] public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx); @@ -939,7 +939,7 @@ namespace Grpc.Core.Internal public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx); [DllImport(ImportName)] - public static unsafe extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); + public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, IntPtr statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); [DllImport(ImportName)] public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx); diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs index 990f6fbb48e..a59afa19118 100644 --- a/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Encode.cs @@ -61,14 +61,11 @@ namespace Grpc.Microbenchmarks var native = NativeMethods.Get(); // nop the native-call via reflection - unsafe - { - NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte* statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { - completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go - return CallError.OK; - }; - native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); - } + NativeMethods.Delegates.grpcsharp_call_send_status_from_server_delegate nop = (CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, IntPtr statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags) => { + completionRegistry.Extract(ctx.Handle).OnComplete(true); // drain the dictionary as we go + return CallError.OK; + }; + native.GetType().GetField(nameof(native.grpcsharp_call_send_status_from_server)).SetValue(native, nop); environment = GrpcEnvironment.AddRef(); metadata = MetadataArraySafeHandle.Create(Metadata.Empty); diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include index 4a31171aa27..ffcaf16bca9 100644 --- a/templates/src/csharp/Grpc.Core/Internal/native_methods.include +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -31,7 +31,7 @@ native_method_signatures = [ 'CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', 'CallError grpcsharp_call_send_message(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata)', 'CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', + 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, IntPtr statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', 'CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx)', 'CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx)', 'CallError grpcsharp_call_start_serverside(CallSafeHandle call, BatchContextSafeHandle ctx)', @@ -107,4 +107,4 @@ for signature in native_method_signatures: native_methods.append({'returntype': match.group(1), 'name': match.group(2), 'params': match.group(3), 'comment': match.group(4)}) return list(native_methods) -%> \ No newline at end of file +%> From 9967e42a7f31f390a91117b0b28812467036ece5 Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 08:32:10 +0100 Subject: [PATCH 583/676] review feedback; naming : Blob => ByteArray --- src/csharp/Grpc.Core.Api/Metadata.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs index cd1ea3b4676..0576cb35304 100644 --- a/src/csharp/Grpc.Core.Api/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -353,7 +353,7 @@ namespace Grpc.Core byte[] arr; if (length == 0) { - arr = EmptyBlob; + arr = EmptyByteArray; } else { // create a local copy in a fresh array @@ -369,7 +369,7 @@ namespace Grpc.Core } } - static readonly byte[] EmptyBlob = new byte[0]; + static readonly byte[] EmptyByteArray = new byte[0]; private static string NormalizeKey(string key) { From 3ab3f5e586cad0754c4d28d5722954f1edbdc0be Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 09:17:01 +0100 Subject: [PATCH 584/676] move WellKnownStrings to top-level file; add tests; refactor --- .../Internal/WellKnownStringsTest.cs | 46 +++++++++++++ .../Internal/MetadataArraySafeHandle.cs | 33 ---------- .../Grpc.Core/Internal/WellKnownStrings.cs | 66 +++++++++++++++++++ 3 files changed, 112 insertions(+), 33 deletions(-) create mode 100644 src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs create mode 100644 src/csharp/Grpc.Core/Internal/WellKnownStrings.cs diff --git a/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs new file mode 100644 index 00000000000..f5c8e01a141 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs @@ -0,0 +1,46 @@ +using System.Text; +using Grpc.Core.Internal; +using NUnit.Framework; + +namespace Grpc.Core.Tests.Internal +{ + public class WellKnownStringsTest + { + [Test] + [TestCase("", true)] + [TestCase("u", false)] + [TestCase("us", false)] + [TestCase("use", false)] + [TestCase("user", false)] + [TestCase("user-", false)] + [TestCase("user-a", false)] + [TestCase("user-ag", false)] + [TestCase("user-age", false)] + [TestCase("user-agent", true)] + [TestCase("user-agent ", false)] + [TestCase("useragent ", false)] + [TestCase("User-Agent", false)] + [TestCase("sdlkfjlskjfdlkjs;lfdksflsdfkh skjdfh sdkfhskdhf skjfhk sdhjkjh", false)] + + // test for endianness snafus (reversed in segments) + [TestCase("ega-resutn", false)] + public unsafe void TestWellKnownStrings(string input, bool expected) + { + // create a copy of the data; no cheating! + byte[] bytes = Encoding.ASCII.GetBytes(input); + fixed(byte* ptr = bytes) + { + string result = WellKnownStrings.TryIdentify(ptr, bytes.Length); + if (expected) Assert.AreEqual(input, result); + else Assert.IsNull(result); + + if (expected) + { + // try again, and check we get the same instance + string again = WellKnownStrings.TryIdentify(ptr, bytes.Length); + Assert.AreSame(result, again); + } + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs index 1663a9d44ac..cc306891119 100644 --- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs @@ -76,39 +76,6 @@ namespace Grpc.Core.Internal return metadata; } - private static class WellKnownStrings - { - // turn a string of ASCII-length 8 into a ulong using the CPUs current - // endianness; this allows us to do the same thing in TryIdentify, - // testing string prefixes (of length >= 8) in a single load/compare - private static unsafe ulong Thunk8(string value) - { - int byteCount = Encoding.ASCII.GetByteCount(value); - if (byteCount != 8) throw new ArgumentException(nameof(value)); - ulong result = 0; - fixed (char* cPtr = value) - { - Encoding.ASCII.GetBytes(cPtr, value.Length, (byte*)&result, byteCount); - } - return result; - } - private static readonly ulong UserAgent = Thunk8("user-age"); - public static unsafe string TryIdentify(byte* source, int length) - { - switch (length) - { - case 10: - // test the first 8 bytes via evilness - ulong first8 = *(ulong*)source; - if (first8 == UserAgent & source[8] == (byte)'n' & source[9] == (byte)'t') - return "user-agent"; - - break; - } - return null; - } - } - internal IntPtr Handle { get diff --git a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs new file mode 100644 index 00000000000..1e78ffdab43 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs @@ -0,0 +1,66 @@ +using System; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Grpc.Core.Internal +{ + /// + /// Utility type for identifying "well-known" strings (i.e. headers/keys etc that + /// we expect to see frequently, and don't want to allocate lots of copies of) + /// + internal static class WellKnownStrings + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe ulong Coerce64(byte* value) + { + return *(ulong*)value; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe uint Coerce32(byte* value) + { + return *(uint*)value; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe ushort Coerce16(byte* value) + { + return *(ushort*)value; + } + + /// + /// Test whether the provided byte sequence is recognized as a well-known string; if + /// so, return a shared instance of that string; otherwise, return null + /// + public static unsafe string TryIdentify(byte* source, int length) + { + // note: the logic here is hard-coded to constants for optimal processing; + // refer to an ASCII/hex converter (and remember to reverse **segments** for little-endian) + if (BitConverter.IsLittleEndian) // this is a JIT intrinsic; branch removal happens on modern runtimes + { + switch (length) + { + case 0: return ""; + case 10: + switch(Coerce64(source)) + { + case 0x6567612d72657375: return Coerce16(source + 8) == 0x746e ? "user-agent" : null; + } + break; + } + } + else + { + switch (length) + { + case 0: return ""; + case 10: + switch (Coerce64(source)) + { + case 0x757365722d616765: return Coerce16(source + 8) == 0x6e74 ? "user-agent" : null; + } + break; + } + } + return null; + } + } +} From 0628990feb79736d30949951f6e64fb34b157597 Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 09:24:15 +0100 Subject: [PATCH 585/676] UTF8 decode: remove "unsafe" from a bunch of places that don't need it any more --- src/csharp/Grpc.Core.Api/Metadata.cs | 6 +++--- src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs | 2 ++ .../Grpc.Core/Internal/MetadataArraySafeHandle.cs | 6 +++--- src/csharp/Grpc.Core/Internal/WellKnownStrings.cs | 11 +++++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs index 0576cb35304..f7f0ae1c93a 100644 --- a/src/csharp/Grpc.Core.Api/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -346,7 +346,7 @@ namespace Grpc.Core /// Creates a binary value or ascii value metadata entry from data received from the native layer. /// We trust C core to give us well-formed data, so we don't perform any checks or defensive copying. /// - internal static unsafe Entry CreateUnsafe(string key, byte* source, int length) + internal static Entry CreateUnsafe(string key, IntPtr source, int length) { if (HasBinaryHeaderSuffix(key)) { @@ -358,13 +358,13 @@ namespace Grpc.Core else { // create a local copy in a fresh array arr = new byte[length]; - Marshal.Copy(new IntPtr(source), arr, 0, length); + Marshal.Copy(source, arr, 0, length); } return new Entry(key, null, arr); } else { - string s = length == 0 ? "" : EncodingASCII.GetString(source, length); + string s = EncodingASCII.GetString(source, length); return new Entry(key, s, null); } } diff --git a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs index ef38baf5cc4..b516ae0993a 100644 --- a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs +++ b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Text; namespace Grpc.Core.Api.Utils @@ -27,6 +28,7 @@ namespace Grpc.Core.Api.Utils /// /// Converts IntPtr pointing to a encoded byte array to a string using the provided Encoding. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe string GetString(this Encoding encoding, IntPtr ptr, int len) { return len == 0 ? "" : encoding.GetString((byte*)ptr.ToPointer(), len); diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs index cc306891119..3edfbfa3bfd 100644 --- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs @@ -50,7 +50,7 @@ namespace Grpc.Core.Internal /// /// Reads metadata from pointer to grpc_metadata_array /// - public static unsafe Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray) + public static Metadata ReadMetadataFromPtrUnsafe(IntPtr metadataArray) { if (metadataArray == IntPtr.Zero) { @@ -66,12 +66,12 @@ namespace Grpc.Core.Internal UIntPtr keyLen; IntPtr keyPtr = Native.grpcsharp_metadata_array_get_key(metadataArray, index, out keyLen); int keyLen32 = checked((int)keyLen.ToUInt32()); - string key = WellKnownStrings.TryIdentify((byte*)keyPtr.ToPointer(), keyLen32) + string key = WellKnownStrings.TryIdentify(keyPtr, keyLen32) ?? Marshal.PtrToStringAnsi(keyPtr, keyLen32); UIntPtr valueLen; IntPtr valuePtr = Native.grpcsharp_metadata_array_get_value(metadataArray, index, out valueLen); int len32 = checked((int)valueLen.ToUInt64()); - metadata.Add(Metadata.Entry.CreateUnsafe(key, (byte*)valuePtr.ToPointer(), len32)); + metadata.Add(Metadata.Entry.CreateUnsafe(key, valuePtr, len32)); } return metadata; } diff --git a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs index 1e78ffdab43..bf35134c9be 100644 --- a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs +++ b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs @@ -26,6 +26,17 @@ namespace Grpc.Core.Internal return *(ushort*)value; } + + /// + /// Test whether the provided byte sequence is recognized as a well-known string; if + /// so, return a shared instance of that string; otherwise, return null + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe string TryIdentify(IntPtr source, int length) + { + return TryIdentify((byte*)source.ToPointer(), length); + } + /// /// Test whether the provided byte sequence is recognized as a well-known string; if /// so, return a shared instance of that string; otherwise, return null From 47913c20ab9f13fd8ad7f99283ad311983f1feac Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 09:27:18 +0100 Subject: [PATCH 586/676] utf8-encode; fix broken test --- src/csharp/Grpc.Core.Tests/MetadataTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs index 7286f9c9932..0b5f1c76e0c 100644 --- a/src/csharp/Grpc.Core.Tests/MetadataTest.cs +++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs @@ -116,7 +116,7 @@ namespace Grpc.Core.Tests var bytes = new byte[] { (byte)'X', (byte)'y' }; fixed (byte* ptr = bytes) { - var entry = Metadata.Entry.CreateUnsafe("abc", ptr, bytes.Length); + var entry = Metadata.Entry.CreateUnsafe("abc", new IntPtr(ptr), bytes.Length); Assert.IsFalse(entry.IsBinary); Assert.AreEqual("abc", entry.Key); Assert.AreEqual("Xy", entry.Value); @@ -130,7 +130,7 @@ namespace Grpc.Core.Tests var bytes = new byte[] { 1, 2, 3 }; fixed (byte* ptr = bytes) { - var entry = Metadata.Entry.CreateUnsafe("abc-bin", ptr, bytes.Length); + var entry = Metadata.Entry.CreateUnsafe("abc-bin", new IntPtr(ptr), bytes.Length); Assert.IsTrue(entry.IsBinary); Assert.AreEqual("abc-bin", entry.Key); Assert.Throws(typeof(InvalidOperationException), () => { var v = entry.Value; }); From ccbde1365bccfa2450011537b89ea8a8bcd86031 Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 09:56:45 +0100 Subject: [PATCH 587/676] add missing copyright --- .../Grpc.Core.Api/Utils/EncodingExtensions.cs | 16 ++++++++++++++++ .../Internal/WellKnownStringsTest.cs | 16 ++++++++++++++++ .../Grpc.Core/Internal/WellKnownStrings.cs | 17 ++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs index b516ae0993a..7d520d30eae 100644 --- a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs +++ b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs @@ -1,3 +1,19 @@ +#region Copyright notice and license +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + using System; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs index f5c8e01a141..285f7a12d0a 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs @@ -1,3 +1,19 @@ +#region Copyright notice and license +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + using System.Text; using Grpc.Core.Internal; using NUnit.Framework; diff --git a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs index bf35134c9be..4b95d1f368d 100644 --- a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs +++ b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs @@ -1,6 +1,21 @@ +#region Copyright notice and license +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + using System; using System.Runtime.CompilerServices; -using System.Text; namespace Grpc.Core.Internal { From b98cc917a77dbec83fa09bc2ff5fc30be0447eea Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 4 Jul 2019 09:58:06 +0100 Subject: [PATCH 588/676] remove changes to .Generated.cs --- .../Grpc.Core/Internal/NativeMethods.Generated.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index d98f0226e3f..170fc5c5657 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -266,10 +266,7 @@ namespace Grpc.Core.Internal this.grpcsharp_call_start_duplex_streaming = DllImportsFromStaticLib.grpcsharp_call_start_duplex_streaming; this.grpcsharp_call_send_message = DllImportsFromStaticLib.grpcsharp_call_send_message; this.grpcsharp_call_send_close_from_client = DllImportsFromStaticLib.grpcsharp_call_send_close_from_client; - unsafe - { - this.grpcsharp_call_send_status_from_server = DllImportsFromStaticLib.grpcsharp_call_send_status_from_server; - } + this.grpcsharp_call_send_status_from_server = DllImportsFromStaticLib.grpcsharp_call_send_status_from_server; this.grpcsharp_call_recv_message = DllImportsFromStaticLib.grpcsharp_call_recv_message; this.grpcsharp_call_recv_initial_metadata = DllImportsFromStaticLib.grpcsharp_call_recv_initial_metadata; this.grpcsharp_call_start_serverside = DllImportsFromStaticLib.grpcsharp_call_start_serverside; @@ -369,10 +366,7 @@ namespace Grpc.Core.Internal this.grpcsharp_call_start_duplex_streaming = DllImportsFromSharedLib.grpcsharp_call_start_duplex_streaming; this.grpcsharp_call_send_message = DllImportsFromSharedLib.grpcsharp_call_send_message; this.grpcsharp_call_send_close_from_client = DllImportsFromSharedLib.grpcsharp_call_send_close_from_client; - unsafe - { - this.grpcsharp_call_send_status_from_server = DllImportsFromSharedLib.grpcsharp_call_send_status_from_server; - } + this.grpcsharp_call_send_status_from_server = DllImportsFromSharedLib.grpcsharp_call_send_status_from_server; this.grpcsharp_call_recv_message = DllImportsFromSharedLib.grpcsharp_call_recv_message; this.grpcsharp_call_recv_initial_metadata = DllImportsFromSharedLib.grpcsharp_call_recv_initial_metadata; this.grpcsharp_call_start_serverside = DllImportsFromSharedLib.grpcsharp_call_start_serverside; From 2ebbf220ab6d859831b0f77383eb1a9d01bb2255 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Jul 2019 11:48:49 -0400 Subject: [PATCH 589/676] fix C# sanity and other nits --- src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs | 2 +- src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs | 4 ++-- src/csharp/Grpc.Core/Internal/WellKnownStrings.cs | 2 +- src/csharp/tests.json | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs index 7d520d30eae..080fbcd5c12 100644 --- a/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs +++ b/src/csharp/Grpc.Core.Api/Utils/EncodingExtensions.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015 gRPC authors. +// Copyright 2019 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs index 285f7a12d0a..4c89b993238 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/WellKnownStringsTest.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015 gRPC authors. +// Copyright 2019 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ using System.Text; using Grpc.Core.Internal; using NUnit.Framework; -namespace Grpc.Core.Tests.Internal +namespace Grpc.Core.Internal.Tests { public class WellKnownStringsTest { diff --git a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs index 4b95d1f368d..fa33e9a1fe4 100644 --- a/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs +++ b/src/csharp/Grpc.Core/Internal/WellKnownStrings.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015 gRPC authors. +// Copyright 2019 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/csharp/tests.json b/src/csharp/tests.json index cacdb305d2e..2eb786e0983 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -14,6 +14,7 @@ "Grpc.Core.Internal.Tests.ReusableSliceBufferTest", "Grpc.Core.Internal.Tests.SliceTest", "Grpc.Core.Internal.Tests.TimespecTest", + "Grpc.Core.Internal.Tests.WellKnownStringsTest", "Grpc.Core.Tests.AppDomainUnloadTest", "Grpc.Core.Tests.AuthContextTest", "Grpc.Core.Tests.AuthPropertyTest", From fbd5a47181020a1c83141b5295ac055e44949a56 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Jul 2019 08:20:38 -0400 Subject: [PATCH 590/676] use System.Memory and Span<> on all TFMs --- .../Grpc.Core.Api/DeserializationContext.cs | 4 +--- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 9 +------ .../Grpc.Core.Tests/Grpc.Core.Tests.csproj | 4 ---- .../DefaultDeserializationContextTest.cs | 14 ++--------- .../Internal/FakeBufferReaderManagerTest.cs | 2 +- .../Internal/ReusableSliceBufferTest.cs | 17 +++---------- .../Grpc.Core.Tests/Internal/SliceTest.cs | 21 ++-------------- src/csharp/Grpc.Core/Grpc.Core.csproj | 6 ++--- .../Internal/DefaultDeserializationContext.cs | 24 ++----------------- .../Grpc.Core/Internal/ReusableSliceBuffer.cs | 3 --- src/csharp/Grpc.Core/Internal/Slice.cs | 9 ------- 11 files changed, 14 insertions(+), 99 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/DeserializationContext.cs b/src/csharp/Grpc.Core.Api/DeserializationContext.cs index 966bcfa8c8e..eb00f67601e 100644 --- a/src/csharp/Grpc.Core.Api/DeserializationContext.cs +++ b/src/csharp/Grpc.Core.Api/DeserializationContext.cs @@ -48,13 +48,12 @@ namespace Grpc.Core throw new NotImplementedException(); } -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY /// /// Gets the entire payload as a ReadOnlySequence. /// The ReadOnlySequence is only valid for the duration of the deserializer routine and the caller must not access it after the deserializer returns. /// Using the read only sequence is the most efficient way to access the message payload. Where possible it allows directly /// accessing the received payload without needing to perform any buffer copying or buffer allocations. - /// NOTE: This method is only available in the netstandard2.0 build of the library. + /// NOTE: In order to access the payload via this method, your compiler needs to support C# 7.2 (to be able to use the Span type). /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// @@ -63,6 +62,5 @@ namespace Grpc.Core { throw new NotImplementedException(); } -#endif } } diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 0a958299ec8..a0d41a260da 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -20,18 +20,11 @@ true - - $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY - - - - - - + diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 693646bea1c..1aa314f4aec 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -9,10 +9,6 @@ true - - $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY - - diff --git a/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs index 63baab31624..8b635f9288f 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/DefaultDeserializationContextTest.cs @@ -17,18 +17,14 @@ #endregion using System; +using System.Buffers; using System.Collections.Generic; +using System.Runtime.InteropServices; using Grpc.Core; using Grpc.Core.Internal; using Grpc.Core.Utils; using NUnit.Framework; -using System.Runtime.InteropServices; - -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY -using System.Buffers; -#endif - namespace Grpc.Core.Internal.Tests { public class DefaultDeserializationContextTest @@ -47,7 +43,6 @@ namespace Grpc.Core.Internal.Tests fakeBufferReaderManager.Dispose(); } -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY [TestCase] public void PayloadAsReadOnlySequence_ZeroSegmentPayload() { @@ -118,7 +113,6 @@ namespace Grpc.Core.Internal.Tests Assert.IsFalse(segmentEnumerator.MoveNext()); } -#endif [TestCase] public void NullPayloadNotAllowed() @@ -196,9 +190,7 @@ namespace Grpc.Core.Internal.Tests // Getting payload multiple times is illegal Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsNewBuffer()); -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY Assert.Throws(typeof(InvalidOperationException), () => context.PayloadAsReadOnlySequence()); -#endif } [TestCase] @@ -215,9 +207,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual(0, context.PayloadLength); Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsNewBuffer()); -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY Assert.Throws(typeof(NullReferenceException), () => context.PayloadAsReadOnlySequence()); -#endif // Previously reset context can be initialized again var origBuffer2 = GetTestBuffer(50); diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs index 7c4ff652bd3..8211b7fe00c 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeBufferReaderManagerTest.cs @@ -103,7 +103,7 @@ namespace Grpc.Core.Internal.Tests private void AssertSliceDataEqual(byte[] expected, Slice actual) { var actualSliceData = new byte[actual.Length]; - actual.CopyTo(new ArraySegment(actualSliceData)); + actual.ToSpanUnsafe().CopyTo(actualSliceData); CollectionAssert.AreEqual(expected, actualSliceData); } diff --git a/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs index 7630785aef4..bfe4f6451d0 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/ReusableSliceBufferTest.cs @@ -17,19 +17,15 @@ #endregion using System; +using System.Buffers; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using Grpc.Core; using Grpc.Core.Internal; using Grpc.Core.Utils; using NUnit.Framework; -using System.Runtime.InteropServices; - -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY -using System.Buffers; -#endif - namespace Grpc.Core.Internal.Tests { // Converts IBufferReader into instances of ReadOnlySequence @@ -50,7 +46,6 @@ namespace Grpc.Core.Internal.Tests fakeBufferReaderManager.Dispose(); } -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY [TestCase] public void NullPayload() { @@ -131,13 +126,7 @@ namespace Grpc.Core.Internal.Tests } return result; } -#else - [TestCase] - public void OnlySupportedOnNetCore() - { - // Test case needs to exist to make C# sanity test happy. - } -#endif + private byte[] GetTestBuffer(int length) { var testBuffer = new byte[length]; diff --git a/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs index eb090bbfa50..ff4d74727b5 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/SliceTest.cs @@ -33,7 +33,7 @@ namespace Grpc.Core.Internal.Tests [TestCase(10)] [TestCase(100)] [TestCase(1000)] - public void SliceFromNativePtr_CopyToArraySegment(int bufferLength) + public void SliceFromNativePtr_Copy(int bufferLength) { var origBuffer = GetTestBuffer(bufferLength); var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); @@ -43,7 +43,7 @@ namespace Grpc.Core.Internal.Tests Assert.AreEqual(bufferLength, slice.Length); var newBuffer = new byte[bufferLength]; - slice.CopyTo(new ArraySegment(newBuffer)); + slice.ToSpanUnsafe().CopyTo(newBuffer); CollectionAssert.AreEqual(origBuffer, newBuffer); } finally @@ -52,23 +52,6 @@ namespace Grpc.Core.Internal.Tests } } - [TestCase] - public void SliceFromNativePtr_CopyToArraySegmentTooSmall() - { - var origBuffer = GetTestBuffer(100); - var gcHandle = GCHandle.Alloc(origBuffer, GCHandleType.Pinned); - try - { - var slice = new Slice(gcHandle.AddrOfPinnedObject(), origBuffer.Length); - var tooSmall = new byte[origBuffer.Length - 1]; - Assert.Catch(typeof(ArgumentException), () => slice.CopyTo(new ArraySegment(tooSmall))); - } - finally - { - gcHandle.Free(); - } - } - // create a buffer of given size and fill it with some data private byte[] GetTestBuffer(int length) { diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 1844ce335bc..b7c7851a34b 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -23,9 +23,8 @@ true - + 7.2 - $(DefineConstants);GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY @@ -100,8 +99,7 @@ - - + diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs index 946c37de190..b668ea18841 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs @@ -16,13 +16,10 @@ #endregion -using Grpc.Core.Utils; using System; -using System.Threading; - -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY using System.Buffers; -#endif +using System.Threading; +using Grpc.Core.Utils; namespace Grpc.Core.Internal { @@ -33,9 +30,7 @@ namespace Grpc.Core.Internal IBufferReader bufferReader; int payloadLength; -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY ReusableSliceBuffer cachedSliceBuffer = new ReusableSliceBuffer(); -#endif public DefaultDeserializationContext() { @@ -51,14 +46,12 @@ namespace Grpc.Core.Internal return buffer; } -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY public override ReadOnlySequence PayloadAsReadOnlySequence() { var sequence = cachedSliceBuffer.PopulateFrom(bufferReader); GrpcPreconditions.CheckState(sequence.Length == payloadLength); return sequence; } -#endif public void Initialize(IBufferReader bufferReader) { @@ -70,9 +63,7 @@ namespace Grpc.Core.Internal { this.bufferReader = null; this.payloadLength = 0; -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY this.cachedSliceBuffer.Invalidate(); -#endif } public static DefaultDeserializationContext GetInitializedThreadLocal(IBufferReader bufferReader) @@ -84,18 +75,7 @@ namespace Grpc.Core.Internal private void FillContinguousBuffer(IBufferReader reader, byte[] destination) { -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY PayloadAsReadOnlySequence().CopyTo(new Span(destination)); -#else - int offset = 0; - while (reader.TryGetNextSlice(out Slice slice)) - { - slice.CopyTo(new ArraySegment(destination, offset, (int)slice.Length)); - offset += (int)slice.Length; - } - // check that we filled the entire destination - GrpcPreconditions.CheckState(offset == payloadLength); -#endif } } } diff --git a/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs index 2d38509e511..078e59e9d1b 100644 --- a/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs +++ b/src/csharp/Grpc.Core/Internal/ReusableSliceBuffer.cs @@ -16,8 +16,6 @@ #endregion -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY - using Grpc.Core.Utils; using System; using System.Threading; @@ -145,4 +143,3 @@ namespace Grpc.Core.Internal } } } -#endif diff --git a/src/csharp/Grpc.Core/Internal/Slice.cs b/src/csharp/Grpc.Core/Internal/Slice.cs index 22eb9537951..b6e07014808 100644 --- a/src/csharp/Grpc.Core/Internal/Slice.cs +++ b/src/csharp/Grpc.Core/Internal/Slice.cs @@ -40,14 +40,6 @@ namespace Grpc.Core.Internal public int Length => length; - // copies data of the slice to given span. - // there needs to be enough space in the destination buffer - public void CopyTo(ArraySegment destination) - { - Marshal.Copy(dataPtr, destination.Array, destination.Offset, length); - } - -#if GRPC_CSHARP_SUPPORT_SYSTEM_MEMORY public Span ToSpanUnsafe() { unsafe @@ -55,7 +47,6 @@ namespace Grpc.Core.Internal return new Span((byte*) dataPtr, length); } } -#endif /// /// Returns a that represents the current . From 05772b699fe9496c41b516c221698e8610c45dd1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Jul 2019 08:23:12 -0400 Subject: [PATCH 591/676] a bit of cleanup --- .../Grpc.Core/Internal/DefaultDeserializationContext.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs index b668ea18841..7b5997b3fed 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs @@ -42,7 +42,7 @@ namespace Grpc.Core.Internal public override byte[] PayloadAsNewBuffer() { var buffer = new byte[payloadLength]; - FillContinguousBuffer(bufferReader, buffer); + PayloadAsReadOnlySequence().CopyTo(buffer); return buffer; } @@ -72,10 +72,5 @@ namespace Grpc.Core.Internal instance.Initialize(bufferReader); return instance; } - - private void FillContinguousBuffer(IBufferReader reader, byte[] destination) - { - PayloadAsReadOnlySequence().CopyTo(new Span(destination)); - } } } From af8c8a88e3e45073b0f439b0950da68b5a412b66 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 8 Jul 2019 16:24:16 +0200 Subject: [PATCH 592/676] Delete the exited container after running python bazel_deps.sh --- tools/distrib/python/bazel_deps.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/distrib/python/bazel_deps.sh b/tools/distrib/python/bazel_deps.sh index 5f4ee1d6c4d..67896f10bd8 100755 --- a/tools/distrib/python/bazel_deps.sh +++ b/tools/distrib/python/bazel_deps.sh @@ -26,6 +26,7 @@ else docker build -t bazel_local_img tools/dockerfile/test/sanity docker run -v "$(realpath .):/src/grpc/:ro" \ -w /src/grpc/third_party/protobuf \ + --rm=true \ bazel_local_img \ bazel query 'deps('$1')' fi From 1bada10afb3b82663c7c6007fcd0ed989a745a7a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 8 Jul 2019 12:00:37 -0400 Subject: [PATCH 593/676] add new dependencies to Unity package --- src/csharp/build_unitypackage.bat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 4211d70b235..06552e8464b 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -65,6 +65,9 @@ copy /Y nativelibs\csharp_ext_macos_ios\libgrpc.a unitypackage\unitypackage_skel @rem add gRPC dependencies @rem TODO(jtattermusch): also include XMLdoc copy /Y Grpc.Core\bin\Release\net45\System.Interactive.Async.dll unitypackage\unitypackage_skeleton\Plugins\System.Interactive.Async\lib\net45\System.Interactive.Async.dll || goto :error +copy /Y Grpc.Core\bin\Release\net45\System.Runtime.CompilerServices.Unsafe.dll unitypackage\unitypackage_skeleton\Plugins\System.Runtime.CompilerServices.Unsafe\lib\net45\System.Runtime.CompilerServices.Unsafe.dll || goto :error +copy /Y Grpc.Core\bin\Release\net45\System.Buffers.dll unitypackage\unitypackage_skeleton\Plugins\System.Buffers\lib\net45\System.Buffers.dll || goto :error +copy /Y Grpc.Core\bin\Release\net45\System.Memory.dll unitypackage\unitypackage_skeleton\Plugins\System.Memory\lib\net45\System.Memory.dll || goto :error @rem add Google.Protobuf @rem TODO(jtattermusch): also include XMLdoc From a933d3d00a7fd9d0a89e08977547778b8bb5ede0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 8 Jul 2019 12:06:16 -0400 Subject: [PATCH 594/676] add unity package skeleton for newly added dependencies --- .../Plugins/System.Buffers/lib.meta | 10 ++++++ .../Plugins/System.Buffers/lib/net45.meta | 10 ++++++ .../lib/net45/System.Buffers.dll.meta | 32 +++++++++++++++++++ .../lib/net45/System.Buffers.xml.meta | 9 ++++++ .../Plugins/System.Memory/lib.meta | 10 ++++++ .../Plugins/System.Memory/lib/net45.meta | 10 ++++++ .../lib/net45/System.Memory.dll.meta | 32 +++++++++++++++++++ .../lib/net45/System.Memory.xml.meta | 9 ++++++ .../lib.meta | 10 ++++++ .../lib/net45.meta | 10 ++++++ ...m.Runtime.CompilerServices.Unsafe.dll.meta | 32 +++++++++++++++++++ ...m.Runtime.CompilerServices.Unsafe.xml.meta | 9 ++++++ 12 files changed, 183 insertions(+) create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta new file mode 100644 index 00000000000..d7ae012a397 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd5ddd2522dc301488ffe002106fe0ab +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta new file mode 100644 index 00000000000..9b1748d3e76 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a68443518bcd1d44ba88a871dcab0c83 +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta new file mode 100644 index 00000000000..bb910fe9229 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +timeCreated: 1531219386 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta new file mode 100644 index 00000000000..53f91502bd6 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6fc38864f2d3dde46b3833c62c91a008 +timeCreated: 1531219386 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta new file mode 100644 index 00000000000..d7ae012a397 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd5ddd2522dc301488ffe002106fe0ab +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta new file mode 100644 index 00000000000..9b1748d3e76 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a68443518bcd1d44ba88a871dcab0c83 +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta new file mode 100644 index 00000000000..bb910fe9229 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +timeCreated: 1531219386 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta new file mode 100644 index 00000000000..53f91502bd6 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6fc38864f2d3dde46b3833c62c91a008 +timeCreated: 1531219386 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta new file mode 100644 index 00000000000..d7ae012a397 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: bd5ddd2522dc301488ffe002106fe0ab +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta new file mode 100644 index 00000000000..9b1748d3e76 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a68443518bcd1d44ba88a871dcab0c83 +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta new file mode 100644 index 00000000000..bb910fe9229 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +timeCreated: 1531219386 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta new file mode 100644 index 00000000000..53f91502bd6 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6fc38864f2d3dde46b3833c62c91a008 +timeCreated: 1531219386 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 06d8d07a9892d058c052339f9c8cb692312c32a6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 8 Jul 2019 11:12:10 -0700 Subject: [PATCH 595/676] Remove the unused import --- src/python/grpcio_tests/tests/unit/_signal_handling_test.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py index 9d0d64709af..467b8df27f9 100644 --- a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py +++ b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py @@ -13,8 +13,6 @@ # limitations under the License. """Test of responsiveness to signals.""" -from __future__ import print_function - import logging import os import signal From 6a71664035fc0ac237bff396c58407901f0b7bd8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 8 Jul 2019 14:41:44 -0400 Subject: [PATCH 596/676] fix sanity test --- templates/src/csharp/build_unitypackage.bat.template | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/src/csharp/build_unitypackage.bat.template b/templates/src/csharp/build_unitypackage.bat.template index d6f2e3c7f0d..07f19c2af3e 100755 --- a/templates/src/csharp/build_unitypackage.bat.template +++ b/templates/src/csharp/build_unitypackage.bat.template @@ -67,6 +67,9 @@ @rem add gRPC dependencies @rem TODO(jtattermusch): also include XMLdoc copy /Y Grpc.Core\bin\Release\net45\System.Interactive.Async.dll unitypackage\unitypackage_skeleton\Plugins\System.Interactive.Async\lib\net45\System.Interactive.Async.dll || goto :error + copy /Y Grpc.Core\bin\Release\net45\System.Runtime.CompilerServices.Unsafe.dll unitypackage\unitypackage_skeleton\Plugins\System.Runtime.CompilerServices.Unsafe\lib\net45\System.Runtime.CompilerServices.Unsafe.dll || goto :error + copy /Y Grpc.Core\bin\Release\net45\System.Buffers.dll unitypackage\unitypackage_skeleton\Plugins\System.Buffers\lib\net45\System.Buffers.dll || goto :error + copy /Y Grpc.Core\bin\Release\net45\System.Memory.dll unitypackage\unitypackage_skeleton\Plugins\System.Memory\lib\net45\System.Memory.dll || goto :error @rem add Google.Protobuf @rem TODO(jtattermusch): also include XMLdoc From af986fa3d50e080cc0630e16f64f469c69f5be31 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 8 Jul 2019 12:50:03 -0700 Subject: [PATCH 597/676] Revert "Merge pull request #19581 from lidizheng/rf-signal" This reverts commit 6d62eb1b703617ff9165773b6d1e7d28ab84856d, reversing changes made to 70dd0b9b3b70e0923149f6c187834eb81b274401. --- src/python/grpcio_tests/tests/unit/_signal_handling_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py index 467b8df27f9..9d0d64709af 100644 --- a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py +++ b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py @@ -13,6 +13,8 @@ # limitations under the License. """Test of responsiveness to signals.""" +from __future__ import print_function + import logging import os import signal From 2014a519fc082fa65614896ba219a31ae4b7c45f Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 8 Jul 2019 12:50:13 -0700 Subject: [PATCH 598/676] Revert "Merge pull request #19481 from gnossen/main_thread_starvation" This reverts commit 8f044f741f5a39411e04423de0dedd845459f770, reversing changes made to 5ae9afdc55b81a9046ef896cea0327faba56cf36. --- src/python/grpcio/grpc/_channel.py | 151 +++++++---------- src/python/grpcio/grpc/_common.py | 50 ------ src/python/grpcio_tests/commands.py | 2 - src/python/grpcio_tests/tests/tests.json | 1 - .../grpcio_tests/tests/unit/BUILD.bazel | 8 - .../grpcio_tests/tests/unit/_signal_client.py | 84 ---------- .../tests/unit/_signal_handling_test.py | 158 ------------------ 7 files changed, 59 insertions(+), 395 deletions(-) delete mode 100644 src/python/grpcio_tests/tests/unit/_signal_client.py delete mode 100644 src/python/grpcio_tests/tests/unit/_signal_handling_test.py diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 0bf8e03b5ce..24f928ef69f 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -13,7 +13,6 @@ # limitations under the License. """Invocation-side implementation of gRPC Python.""" -import functools import logging import sys import threading @@ -82,6 +81,17 @@ def _unknown_code_details(unknown_cygrpc_code, details): unknown_cygrpc_code, details) +def _wait_once_until(condition, until): + if until is None: + condition.wait() + else: + remaining = until - time.time() + if remaining < 0: + raise grpc.FutureTimeoutError() + else: + condition.wait(timeout=remaining) + + class _RPCState(object): def __init__(self, due, initial_metadata, trailing_metadata, code, details): @@ -168,11 +178,12 @@ def _event_handler(state, response_deserializer): #pylint: disable=too-many-statements def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): - """Consume a request iterator supplied by the user.""" + if cygrpc.is_fork_support_enabled(): + condition_wait_timeout = 1.0 + else: + condition_wait_timeout = None def consume_request_iterator(): # pylint: disable=too-many-branches - # Iterate over the request iterator until it is exhausted or an error - # condition is encountered. while True: return_from_user_request_generator_invoked = False try: @@ -213,19 +224,14 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, state.due.add(cygrpc.OperationType.send_message) else: return - - def _done(): - return (state.code is not None or - cygrpc.OperationType.send_message not in - state.due) - - _common.wait( - state.condition.wait, - _done, - spin_cb=functools.partial( - cygrpc.block_if_fork_in_progress, state)) - if state.code is not None: - return + while True: + state.condition.wait(condition_wait_timeout) + cygrpc.block_if_fork_in_progress(state) + if state.code is None: + if cygrpc.OperationType.send_message not in state.due: + break + else: + return else: return with state.condition: @@ -275,21 +281,13 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too with self._state.condition: return self._state.code is not None - def _is_complete(self): - return self._state.code is not None - def result(self, timeout=None): - """Returns the result of the computation or raises its exception. - - See grpc.Future.result for the full API contract. - """ + until = None if timeout is None else time.time() + timeout with self._state.condition: - timed_out = _common.wait( - self._state.condition.wait, self._is_complete, timeout=timeout) - if timed_out: - raise grpc.FutureTimeoutError() - else: - if self._state.code is grpc.StatusCode.OK: + while True: + if self._state.code is None: + _wait_once_until(self._state.condition, until) + elif self._state.code is grpc.StatusCode.OK: return self._state.response elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -297,17 +295,12 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too raise self def exception(self, timeout=None): - """Return the exception raised by the computation. - - See grpc.Future.exception for the full API contract. - """ + until = None if timeout is None else time.time() + timeout with self._state.condition: - timed_out = _common.wait( - self._state.condition.wait, self._is_complete, timeout=timeout) - if timed_out: - raise grpc.FutureTimeoutError() - else: - if self._state.code is grpc.StatusCode.OK: + while True: + if self._state.code is None: + _wait_once_until(self._state.condition, until) + elif self._state.code is grpc.StatusCode.OK: return None elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -315,17 +308,12 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too return self def traceback(self, timeout=None): - """Access the traceback of the exception raised by the computation. - - See grpc.future.traceback for the full API contract. - """ + until = None if timeout is None else time.time() + timeout with self._state.condition: - timed_out = _common.wait( - self._state.condition.wait, self._is_complete, timeout=timeout) - if timed_out: - raise grpc.FutureTimeoutError() - else: - if self._state.code is grpc.StatusCode.OK: + while True: + if self._state.code is None: + _wait_once_until(self._state.condition, until) + elif self._state.code is grpc.StatusCode.OK: return None elif self._state.cancelled: raise grpc.FutureCancelledError() @@ -357,23 +345,17 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too raise StopIteration() else: raise self - - def _response_ready(): - return ( - self._state.response is not None or - (cygrpc.OperationType.receive_message not in self._state.due - and self._state.code is not None)) - - _common.wait(self._state.condition.wait, _response_ready) - if self._state.response is not None: - response = self._state.response - self._state.response = None - return response - elif cygrpc.OperationType.receive_message not in self._state.due: - if self._state.code is grpc.StatusCode.OK: - raise StopIteration() - elif self._state.code is not None: - raise self + while True: + self._state.condition.wait() + if self._state.response is not None: + response = self._state.response + self._state.response = None + return response + elif cygrpc.OperationType.receive_message not in self._state.due: + if self._state.code is grpc.StatusCode.OK: + raise StopIteration() + elif self._state.code is not None: + raise self def __iter__(self): return self @@ -404,47 +386,32 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too def initial_metadata(self): with self._state.condition: - - def _done(): - return self._state.initial_metadata is not None - - _common.wait(self._state.condition.wait, _done) + while self._state.initial_metadata is None: + self._state.condition.wait() return self._state.initial_metadata def trailing_metadata(self): with self._state.condition: - - def _done(): - return self._state.trailing_metadata is not None - - _common.wait(self._state.condition.wait, _done) + while self._state.trailing_metadata is None: + self._state.condition.wait() return self._state.trailing_metadata def code(self): with self._state.condition: - - def _done(): - return self._state.code is not None - - _common.wait(self._state.condition.wait, _done) + while self._state.code is None: + self._state.condition.wait() return self._state.code def details(self): with self._state.condition: - - def _done(): - return self._state.details is not None - - _common.wait(self._state.condition.wait, _done) + while self._state.details is None: + self._state.condition.wait() return _common.decode(self._state.details) def debug_error_string(self): with self._state.condition: - - def _done(): - return self._state.debug_error_string is not None - - _common.wait(self._state.condition.wait, _done) + while self._state.debug_error_string is None: + self._state.condition.wait() return _common.decode(self._state.debug_error_string) def _repr(self): diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index b4b24738e8f..f69127e38ef 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -15,7 +15,6 @@ import logging -import time import six import grpc @@ -61,8 +60,6 @@ STATUS_CODE_TO_CYGRPC_STATUS_CODE = { CYGRPC_STATUS_CODE_TO_STATUS_CODE) } -MAXIMUM_WAIT_TIMEOUT = 0.1 - def encode(s): if isinstance(s, bytes): @@ -99,50 +96,3 @@ def deserialize(serialized_message, deserializer): def fully_qualified_method(group, method): return '/{}/{}'.format(group, method) - - -def _wait_once(wait_fn, timeout, spin_cb): - wait_fn(timeout=timeout) - if spin_cb is not None: - spin_cb() - - -def wait(wait_fn, wait_complete_fn, timeout=None, spin_cb=None): - """Blocks waiting for an event without blocking the thread indefinitely. - - See https://github.com/grpc/grpc/issues/19464 for full context. CPython's - `threading.Event.wait` and `threading.Condition.wait` methods, if invoked - without a timeout kwarg, may block the calling thread indefinitely. If the - call is made from the main thread, this means that signal handlers may not - run for an arbitrarily long period of time. - - This wrapper calls the supplied wait function with an arbitrary short - timeout to ensure that no signal handler has to wait longer than - MAXIMUM_WAIT_TIMEOUT before executing. - - Args: - wait_fn: A callable acceptable a single float-valued kwarg named - `timeout`. This function is expected to be one of `threading.Event.wait` - or `threading.Condition.wait`. - wait_complete_fn: A callable taking no arguments and returning a bool. - When this function returns true, it indicates that waiting should cease. - timeout: An optional float-valued number of seconds after which the wait - should cease. - spin_cb: An optional Callable taking no arguments and returning nothing. - This callback will be called on each iteration of the spin. This may be - used for, e.g. work related to forking. - - Returns: - True if a timeout was supplied and it was reached. False otherwise. - """ - if timeout is None: - while not wait_complete_fn(): - _wait_once(wait_fn, MAXIMUM_WAIT_TIMEOUT, spin_cb) - else: - end = time.time() + timeout - while not wait_complete_fn(): - remaining = min(end - time.time(), MAXIMUM_WAIT_TIMEOUT) - if remaining < 0: - return True - _wait_once(wait_fn, remaining, spin_cb) - return False diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 166cea101a4..dc0795d4a12 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -145,8 +145,6 @@ class TestGevent(setuptools.Command): 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', - # TODO(https://github.com/grpc/grpc/issues/18980): Reenable. - 'unit._signal_handling_test.SignalHandlingTest', 'unit._metadata_flags_test', 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 16ba4847bc0..cc08d56248a 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -67,7 +67,6 @@ "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth", "unit._server_test.ServerTest", "unit._session_cache_test.SSLSessionCacheTest", - "unit._signal_handling_test.SignalHandlingTest", "unit._version_test.VersionTest", "unit.beta._beta_features_test.BetaFeaturesTest", "unit.beta._beta_features_test.ContextManagementAndLifecycleTest", diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index d21f5a59ad1..a161794f8be 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -16,7 +16,6 @@ GRPCIO_TESTS_UNIT = [ "_credentials_test.py", "_dns_resolver_test.py", "_empty_message_test.py", - "_error_message_encoding_test.py", "_exit_test.py", "_interceptor_test.py", "_invalid_metadata_test.py", @@ -28,7 +27,6 @@ GRPCIO_TESTS_UNIT = [ # "_reconnect_test.py", "_resource_exhausted_test.py", "_rpc_test.py", - "_signal_handling_test.py", # TODO(ghostwriternr): To be added later. # "_server_ssl_cert_config_test.py", "_server_test.py", @@ -41,11 +39,6 @@ py_library( srcs = ["_tcp_proxy.py"], ) -py_library( - name = "_signal_client", - srcs = ["_signal_client.py"], -) - py_library( name = "resources", srcs = ["resources.py"], @@ -94,7 +87,6 @@ py_library( ":_server_shutdown_scenarios", ":_from_grpc_import_star", ":_tcp_proxy", - ":_signal_client", "//src/python/grpcio_tests/tests/unit/framework/common", "//src/python/grpcio_tests/tests/testing", requirement('six'), diff --git a/src/python/grpcio_tests/tests/unit/_signal_client.py b/src/python/grpcio_tests/tests/unit/_signal_client.py deleted file mode 100644 index 65ddd6d858e..00000000000 --- a/src/python/grpcio_tests/tests/unit/_signal_client.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2019 the gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Client for testing responsiveness to signals.""" - -from __future__ import print_function - -import argparse -import functools -import logging -import signal -import sys - -import grpc - -SIGTERM_MESSAGE = "Handling sigterm!" - -UNARY_UNARY = "/test/Unary" -UNARY_STREAM = "/test/ServerStreaming" - -_MESSAGE = b'\x00\x00\x00' - -_ASSERTION_MESSAGE = "Control flow should never reach here." - -# NOTE(gnossen): We use a global variable here so that the signal handler can be -# installed before the RPC begins. If we do not do this, then we may receive the -# SIGINT before the signal handler is installed. I'm not happy with per-process -# global state, but the per-process global state that is signal handlers -# somewhat forces my hand. -per_process_rpc_future = None - - -def handle_sigint(unused_signum, unused_frame): - print(SIGTERM_MESSAGE) - if per_process_rpc_future is not None: - per_process_rpc_future.cancel() - sys.stderr.flush() - sys.exit(0) - - -def main_unary(server_target): - """Initiate a unary RPC to be interrupted by a SIGINT.""" - global per_process_rpc_future # pylint: disable=global-statement - with grpc.insecure_channel(server_target) as channel: - multicallable = channel.unary_unary(UNARY_UNARY) - signal.signal(signal.SIGINT, handle_sigint) - per_process_rpc_future = multicallable.future( - _MESSAGE, wait_for_ready=True) - result = per_process_rpc_future.result() - assert False, _ASSERTION_MESSAGE - - -def main_streaming(server_target): - """Initiate a streaming RPC to be interrupted by a SIGINT.""" - global per_process_rpc_future # pylint: disable=global-statement - with grpc.insecure_channel(server_target) as channel: - signal.signal(signal.SIGINT, handle_sigint) - per_process_rpc_future = channel.unary_stream(UNARY_STREAM)( - _MESSAGE, wait_for_ready=True) - for result in per_process_rpc_future: - pass - assert False, _ASSERTION_MESSAGE - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Signal test client.') - parser.add_argument('server', help='Server target') - parser.add_argument( - 'arity', help='RPC arity', choices=('unary', 'streaming')) - args = parser.parse_args() - if args.arity == 'unary': - main_unary(args.server) - else: - main_streaming(args.server) diff --git a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py b/src/python/grpcio_tests/tests/unit/_signal_handling_test.py deleted file mode 100644 index 9d0d64709af..00000000000 --- a/src/python/grpcio_tests/tests/unit/_signal_handling_test.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright 2019 the gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Test of responsiveness to signals.""" - -from __future__ import print_function - -import logging -import os -import signal -import subprocess -import tempfile -import threading -import unittest -import sys - -import grpc - -from tests.unit import test_common -from tests.unit import _signal_client - -_CLIENT_PATH = os.path.abspath(os.path.realpath(_signal_client.__file__)) -_HOST = 'localhost' - - -class _GenericHandler(grpc.GenericRpcHandler): - - def __init__(self): - self._connected_clients_lock = threading.RLock() - self._connected_clients_event = threading.Event() - self._connected_clients = 0 - - self._unary_unary_handler = grpc.unary_unary_rpc_method_handler( - self._handle_unary_unary) - self._unary_stream_handler = grpc.unary_stream_rpc_method_handler( - self._handle_unary_stream) - - def _on_client_connect(self): - with self._connected_clients_lock: - self._connected_clients += 1 - self._connected_clients_event.set() - - def _on_client_disconnect(self): - with self._connected_clients_lock: - self._connected_clients -= 1 - if self._connected_clients == 0: - self._connected_clients_event.clear() - - def await_connected_client(self): - """Blocks until a client connects to the server.""" - self._connected_clients_event.wait() - - def _handle_unary_unary(self, request, servicer_context): - """Handles a unary RPC. - - Blocks until the client disconnects and then echoes. - """ - stop_event = threading.Event() - - def on_rpc_end(): - self._on_client_disconnect() - stop_event.set() - - servicer_context.add_callback(on_rpc_end) - self._on_client_connect() - stop_event.wait() - return request - - def _handle_unary_stream(self, request, servicer_context): - """Handles a server streaming RPC. - - Blocks until the client disconnects and then echoes. - """ - stop_event = threading.Event() - - def on_rpc_end(): - self._on_client_disconnect() - stop_event.set() - - servicer_context.add_callback(on_rpc_end) - self._on_client_connect() - stop_event.wait() - yield request - - def service(self, handler_call_details): - if handler_call_details.method == _signal_client.UNARY_UNARY: - return self._unary_unary_handler - elif handler_call_details.method == _signal_client.UNARY_STREAM: - return self._unary_stream_handler - else: - return None - - -def _read_stream(stream): - stream.seek(0) - return stream.read() - - -class SignalHandlingTest(unittest.TestCase): - - def setUp(self): - self._server = test_common.test_server() - self._port = self._server.add_insecure_port('{}:0'.format(_HOST)) - self._handler = _GenericHandler() - self._server.add_generic_rpc_handlers((self._handler,)) - self._server.start() - - def tearDown(self): - self._server.stop(None) - - @unittest.skipIf(os.name == 'nt', 'SIGINT not supported on windows') - def testUnary(self): - """Tests that the server unary code path does not stall signal handlers.""" - server_target = '{}:{}'.format(_HOST, self._port) - with tempfile.TemporaryFile(mode='r') as client_stdout: - with tempfile.TemporaryFile(mode='r') as client_stderr: - client = subprocess.Popen( - (sys.executable, _CLIENT_PATH, server_target, 'unary'), - stdout=client_stdout, - stderr=client_stderr) - self._handler.await_connected_client() - client.send_signal(signal.SIGINT) - self.assertFalse(client.wait(), msg=_read_stream(client_stderr)) - client_stdout.seek(0) - self.assertIn(_signal_client.SIGTERM_MESSAGE, - client_stdout.read()) - - @unittest.skipIf(os.name == 'nt', 'SIGINT not supported on windows') - def testStreaming(self): - """Tests that the server streaming code path does not stall signal handlers.""" - server_target = '{}:{}'.format(_HOST, self._port) - with tempfile.TemporaryFile(mode='r') as client_stdout: - with tempfile.TemporaryFile(mode='r') as client_stderr: - client = subprocess.Popen( - (sys.executable, _CLIENT_PATH, server_target, 'streaming'), - stdout=client_stdout, - stderr=client_stderr) - self._handler.await_connected_client() - client.send_signal(signal.SIGINT) - self.assertFalse(client.wait(), msg=_read_stream(client_stderr)) - client_stdout.seek(0) - self.assertIn(_signal_client.SIGTERM_MESSAGE, - client_stdout.read()) - - -if __name__ == '__main__': - logging.basicConfig() - unittest.main(verbosity=2) From 50cb169af06c9165c117e327d88713503f786c4b Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Mon, 8 Jul 2019 13:44:55 -0700 Subject: [PATCH 599/676] add IsValidTarget api to ResolverRegistry --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 + .../resolver/dns/native/dns_resolver.cc | 11 +++-- .../resolver/fake/fake_resolver.cc | 2 + .../resolver/sockaddr/sockaddr_resolver.cc | 44 +++++++++++++------ .../filters/client_channel/resolver_factory.h | 4 ++ .../client_channel/resolver_registry.cc | 11 +++++ .../client_channel/resolver_registry.h | 3 ++ 7 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 43b28bc9650..4e7bb5ec482 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -433,6 +433,8 @@ void AresDnsResolver::StartResolvingLocked() { class AresDnsResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { return true; } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 1abe9ad3e44..bc6d73acac7 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -258,11 +258,16 @@ void NativeDnsResolver::StartResolvingLocked() { class NativeDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver(ResolverArgs args) const override { - if (GPR_UNLIKELY(0 != strcmp(args.uri->authority, ""))) { + bool IsValidUri(const grpc_uri* uri) const override { + if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) { gpr_log(GPR_ERROR, "authority based dns uri's not supported"); - return OrphanablePtr(nullptr); + return false; } + return true; + } + + OrphanablePtr CreateResolver(ResolverArgs args) const override { + if (!IsValidUri(args.uri)) return nullptr; return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index ff728a3dc43..5ecdf4e8d16 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -315,6 +315,8 @@ namespace { class FakeResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { return true; } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 517b9297af4..532fd6df9b7 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -80,24 +80,23 @@ void SockaddrResolver::StartLocked() { void DoNothing(void* ignored) {} -OrphanablePtr CreateSockaddrResolver( - ResolverArgs args, - bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { - if (0 != strcmp(args.uri->authority, "")) { +bool ParseUri(const grpc_uri* uri, + bool parse(const grpc_uri* uri, grpc_resolved_address* dst), + ServerAddressList* addresses) { + if (0 != strcmp(uri->authority, "")) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", - args.uri->scheme); - return nullptr; + uri->scheme); + return false; } // Construct addresses. grpc_slice path_slice = - grpc_slice_new(args.uri->path, strlen(args.uri->path), DoNothing); + grpc_slice_new(uri->path, strlen(uri->path), DoNothing); grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - ServerAddressList addresses; bool errors_found = false; for (size_t i = 0; i < path_parts.count; i++) { - grpc_uri ith_uri = *args.uri; + grpc_uri ith_uri = *uri; UniquePtr part_str(grpc_slice_to_c_string(path_parts.slices[i])); ith_uri.path = part_str.get(); grpc_resolved_address addr; @@ -105,13 +104,20 @@ OrphanablePtr CreateSockaddrResolver( errors_found = true; break; } - addresses.emplace_back(addr, nullptr /* args */); + if (addresses != nullptr) { + addresses->emplace_back(addr, nullptr /* args */); + } } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); - if (errors_found) { - return OrphanablePtr(nullptr); - } + return !errors_found; +} + +OrphanablePtr CreateSockaddrResolver( + ResolverArgs args, + bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { + ServerAddressList addresses; + if (!ParseUri(args.uri, parse, &addresses)) return nullptr; // Instantiate resolver. return OrphanablePtr( New(std::move(addresses), std::move(args))); @@ -119,6 +125,10 @@ OrphanablePtr CreateSockaddrResolver( class IPv4ResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_ipv4, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4); } @@ -128,6 +138,10 @@ class IPv4ResolverFactory : public ResolverFactory { class IPv6ResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_ipv6, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6); } @@ -138,6 +152,10 @@ class IPv6ResolverFactory : public ResolverFactory { #ifdef GRPC_HAVE_UNIX_SOCKET class UnixResolverFactory : public ResolverFactory { public: + bool IsValidUri(const grpc_uri* uri) const override { + return ParseUri(uri, grpc_parse_unix, nullptr); + } + OrphanablePtr CreateResolver(ResolverArgs args) const override { return CreateSockaddrResolver(std::move(args), grpc_parse_unix); } diff --git a/src/core/ext/filters/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h index 273fd8d24f0..7fed48b9570 100644 --- a/src/core/ext/filters/client_channel/resolver_factory.h +++ b/src/core/ext/filters/client_channel/resolver_factory.h @@ -47,6 +47,10 @@ struct ResolverArgs { class ResolverFactory { public: + /// Returns a bool indicating whether the input uri is valid to create a + /// resolver. + virtual bool IsValidUri(const grpc_uri* uri) const GRPC_ABSTRACT; + /// Returns a new resolver instance. virtual OrphanablePtr CreateResolver(ResolverArgs args) const GRPC_ABSTRACT; diff --git a/src/core/ext/filters/client_channel/resolver_registry.cc b/src/core/ext/filters/client_channel/resolver_registry.cc index 5b00eab341e..509c4ef38fa 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.cc +++ b/src/core/ext/filters/client_channel/resolver_registry.cc @@ -132,6 +132,17 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) { return g_state->LookupResolverFactory(scheme); } +bool ResolverRegistry::IsValidTarget(const char* target) { + grpc_uri* uri = nullptr; + char* canonical_target = nullptr; + ResolverFactory* factory = + g_state->FindResolverFactory(target, &uri, &canonical_target); + bool result = factory == nullptr ? false : factory->IsValidUri(uri); + grpc_uri_destroy(uri); + gpr_free(canonical_target); + return result; +} + OrphanablePtr ResolverRegistry::CreateResolver( const char* target, const grpc_channel_args* args, grpc_pollset_set* pollset_set, grpc_combiner* combiner, diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h index 0eec6782609..4248a065439 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.h +++ b/src/core/ext/filters/client_channel/resolver_registry.h @@ -50,6 +50,9 @@ class ResolverRegistry { static void RegisterResolverFactory(UniquePtr factory); }; + /// Checks whether the user input \a target is valid to create a resolver. + static bool IsValidTarget(const char* target); + /// Creates a resolver given \a target. /// First tries to parse \a target as a URI. If this succeeds, tries /// to locate a registered resolver factory based on the URI scheme. From 957fc7bab7d427878d2dd0def19dfffa5cd111fd Mon Sep 17 00:00:00 2001 From: Michael Herold Date: Mon, 8 Jul 2019 16:15:27 -0500 Subject: [PATCH 600/676] Don't require_relative for an absolute path Ruby's `require_relative` method currently converts paths to absolute paths. This idiosyncrasy means that the implementation of the require for the distributed shared library works, however the semantics do not mesh with the semantics of `require_relative`. This is an issue when you redefine `require_relative` and follow the semantics of the method, as [derailed_benchmarks does][1]. This means that any project that uses `grpc` also cannot use that project (which I will also be patching). In the event that a new version of Ruby follows the semantics of the method (whether or not that is likely), this will break as well. By switching to `require` here instead of `require_relative`, we maintain the functionality but do not use a semantically incompatible method to do so. [1]: https://github.com/schneems/derailed_benchmarks/blob/1b0c425720fd6cc575edbb389b434f461cb65989/lib/derailed_benchmarks/core_ext/kernel_require.rb#L24-L27 --- src/ruby/lib/grpc/grpc.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/grpc.rb b/src/ruby/lib/grpc/grpc.rb index 0649dabd606..f52efe36764 100644 --- a/src/ruby/lib/grpc/grpc.rb +++ b/src/ruby/lib/grpc/grpc.rb @@ -17,7 +17,7 @@ begin distrib_lib_dir = File.expand_path(ruby_version_dirname, File.dirname(__FILE__)) if File.directory?(distrib_lib_dir) - require_relative "#{distrib_lib_dir}/grpc_c" + require "#{distrib_lib_dir}/grpc_c" else require 'grpc/grpc_c' end From 6de222a6ad6ea72c0f8d8d95c4bd6dc2a11d10d8 Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Mon, 8 Jul 2019 15:37:21 -0700 Subject: [PATCH 601/676] refactor response generator in client_lb_end2end_test --- .../resolver/fake/fake_resolver.cc | 8 +- test/cpp/end2end/client_lb_end2end_test.cc | 350 +++++++++++------- 2 files changed, 214 insertions(+), 144 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index ff728a3dc43..c48f2321cf4 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -89,9 +89,15 @@ FakeResolver::FakeResolver(ResolverArgs args) : Resolver(args.combiner, std::move(args.result_handler)) { GRPC_CLOSURE_INIT(&reresolution_closure_, ReturnReresolutionResult, this, grpc_combiner_scheduler(combiner())); - channel_args_ = grpc_channel_args_copy(args.args); FakeResolverResponseGenerator* response_generator = FakeResolverResponseGenerator::GetFromArgs(args.args); + // Channels sharing the same subchannels may have different resolver response + // generators. If we don't remove this arg, subchannel pool will create new + // subchannels for the same address instead of reusing existing ones because + // of different values of this channel arg. + const char* args_to_remove[] = {GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR}; + channel_args_ = grpc_channel_args_copy_and_remove( + args.args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove)); if (response_generator != nullptr) { response_generator->resolver_ = this; if (response_generator->has_result_) { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index d499f136ef6..8fc0eacc2fc 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -133,6 +133,59 @@ class MyTestServiceImpl : public TestServiceImpl { std::set clients_; }; +class FakeResolverResponseGeneratorWrapper { + public: + FakeResolverResponseGeneratorWrapper() + : response_generator_(grpc_core::MakeRefCounted< + grpc_core::FakeResolverResponseGenerator>()) {} + + FakeResolverResponseGeneratorWrapper( + FakeResolverResponseGeneratorWrapper&& other) { + response_generator_ = std::move(other.response_generator_); + } + + void SetNextResolution(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetResponse(BuildFakeResults(ports)); + } + + void SetNextResolutionUponError(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetReresolutionResponse(BuildFakeResults(ports)); + } + + void SetFailureOnReresolution() { + grpc_core::ExecCtx exec_ctx; + response_generator_->SetFailureOnReresolution(); + } + + grpc_core::FakeResolverResponseGenerator* Get() const { + return response_generator_.get(); + } + + private: + static grpc_core::Resolver::Result BuildFakeResults( + const std::vector& ports) { + grpc_core::Resolver::Result result; + for (const int& port : ports) { + char* lb_uri_str; + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); + grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); + grpc_uri_destroy(lb_uri); + gpr_free(lb_uri_str); + } + return result; + } + + grpc_core::RefCountedPtr + response_generator_; +}; + class ClientLbEnd2endTest : public ::testing::Test { protected: ClientLbEnd2endTest() @@ -147,11 +200,7 @@ class ClientLbEnd2endTest : public ::testing::Test { GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } - void SetUp() override { - grpc_init(); - response_generator_ = - grpc_core::MakeRefCounted(); - } + void SetUp() override { grpc_init(); } void TearDown() override { for (size_t i = 0; i < servers_.size(); ++i) { @@ -186,38 +235,6 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - grpc_core::Resolver::Result BuildFakeResults(const std::vector& ports) { - grpc_core::Resolver::Result result; - for (const int& port : ports) { - char* lb_uri_str; - gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); - grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); - GPR_ASSERT(lb_uri != nullptr); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - result.addresses.emplace_back(address.addr, address.len, - nullptr /* args */); - grpc_uri_destroy(lb_uri); - gpr_free(lb_uri_str); - } - return result; - } - - void SetNextResolution(const std::vector& ports) { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetResponse(BuildFakeResults(ports)); - } - - void SetNextResolutionUponError(const std::vector& ports) { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetReresolutionResponse(BuildFakeResults(ports)); - } - - void SetFailureOnReresolution() { - grpc_core::ExecCtx exec_ctx; - response_generator_->SetFailureOnReresolution(); - } - std::vector GetServersPorts(size_t start_index = 0) { std::vector ports; for (size_t i = start_index; i < servers_.size(); ++i) { @@ -226,6 +243,10 @@ class ClientLbEnd2endTest : public ::testing::Test { return ports; } + FakeResolverResponseGeneratorWrapper BuildResolverResponseGenerator() { + return FakeResolverResponseGeneratorWrapper(); + } + std::unique_ptr BuildStub( const std::shared_ptr& channel) { return grpc::testing::EchoTestService::NewStub(channel); @@ -233,12 +254,13 @@ class ClientLbEnd2endTest : public ::testing::Test { std::shared_ptr BuildChannel( const grpc::string& lb_policy_name, + const FakeResolverResponseGeneratorWrapper& response_generator, ChannelArguments args = ChannelArguments()) { if (lb_policy_name.size() > 0) { args.SetLoadBalancingPolicyName(lb_policy_name); } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); + response_generator.Get()); return ::grpc::CreateCustomChannel("fake:///", creds_, args); } @@ -401,8 +423,6 @@ class ClientLbEnd2endTest : public ::testing::Test { const grpc::string server_host_; std::unique_ptr stub_; std::vector> servers_; - grpc_core::RefCountedPtr - response_generator_; const grpc::string kRequestMessage_; std::shared_ptr creds_; }; @@ -410,7 +430,8 @@ class ClientLbEnd2endTest : public ::testing::Test { TEST_F(ClientLbEnd2endTest, ChannelStateConnectingWhenResolving) { const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel(""); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("", response_generator); auto stub = BuildStub(channel); // Initial state should be IDLE. EXPECT_EQ(channel->GetState(false /* try_to_connect */), GRPC_CHANNEL_IDLE); @@ -423,7 +444,7 @@ TEST_F(ClientLbEnd2endTest, ChannelStateConnectingWhenResolving) { EXPECT_EQ(channel->GetState(false /* try_to_connect */), GRPC_CHANNEL_CONNECTING); // Return a resolver result, which allows the connection attempt to proceed. - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); // We should eventually transition into state READY. EXPECT_TRUE(WaitForChannelReady(channel.get())); } @@ -432,9 +453,11 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel(""); // test that pick first is the default. + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel( + "", response_generator); // test that pick first is the default. auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -454,19 +477,22 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { } TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) { - StartServers(1); // Single server - auto channel = BuildChannel(""); // test that pick first is the default. + StartServers(1); // Single server + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel( + "", response_generator); // test that pick first is the default. auto stub = BuildStub(channel); - SetNextResolution({servers_[0]->port_}); + response_generator.SetNextResolution({servers_[0]->port_}); WaitForServer(stub, 0, DEBUG_LOCATION); // Create a new channel and its corresponding PF LB policy, which will pick // the subchannels in READY state from the previous RPC against the same // target (even if it happened over a different channel, because subchannels // are globally reused). Progress should happen without any transition from // this READY state. - auto second_channel = BuildChannel(""); + auto second_response_generator = BuildResolverResponseGenerator(); + auto second_channel = BuildChannel("", second_response_generator); auto second_stub = BuildStub(second_channel); - SetNextResolution({servers_[0]->port_}); + second_response_generator.SetNextResolution({servers_[0]->port_}); CheckRpcSendOk(second_stub, DEBUG_LOCATION); } @@ -479,16 +505,18 @@ TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) { grpc_pick_unused_port_or_die()}; CreateServers(2, ports); StartServer(1); - auto channel1 = BuildChannel("pick_first", args); + auto response_generator1 = BuildResolverResponseGenerator(); + auto channel1 = BuildChannel("pick_first", response_generator1, args); auto stub1 = BuildStub(channel1); - SetNextResolution(ports); + response_generator1.SetNextResolution(ports); // Wait for second server to be ready. WaitForServer(stub1, 1, DEBUG_LOCATION); // Create a second channel with the same addresses. Its PF instance // should immediately pick the second subchannel, since it's already // in READY state. - auto channel2 = BuildChannel("pick_first", args); - SetNextResolution(ports); + auto response_generator2 = BuildResolverResponseGenerator(); + auto channel2 = BuildChannel("pick_first", response_generator2, args); + response_generator2.SetNextResolution(ports); // Check that the channel reports READY without waiting for the // initial backoff. EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */)); @@ -500,9 +528,10 @@ TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); const std::vector ports = {grpc_pick_unused_port_or_die()}; const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); - auto channel = BuildChannel("pick_first", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // The channel won't become connected (there's no server). ASSERT_FALSE(channel->WaitForConnected( grpc_timeout_milliseconds_to_deadline(kInitialBackOffMs * 2))); @@ -529,9 +558,10 @@ TEST_F(ClientLbEnd2endTest, PickFirstBackOffMinReconnect) { constexpr int kMinReconnectBackOffMs = 1000; args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kMinReconnectBackOffMs); const std::vector ports = {grpc_pick_unused_port_or_die()}; - auto channel = BuildChannel("pick_first", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // Make connection delay a 10% longer than it's willing to in order to make // sure we are hitting the codepath that waits for the min reconnect backoff. gpr_atm_rel_store(&g_connection_delay_ms, kMinReconnectBackOffMs * 1.10); @@ -554,9 +584,10 @@ TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) { constexpr int kInitialBackOffMs = 1000; args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); const std::vector ports = {grpc_pick_unused_port_or_die()}; - auto channel = BuildChannel("pick_first", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // The channel won't become connected (there's no server). EXPECT_FALSE( channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10))); @@ -585,9 +616,10 @@ TEST_F(ClientLbEnd2endTest, constexpr int kInitialBackOffMs = 1000; args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs); const std::vector ports = {grpc_pick_unused_port_or_die()}; - auto channel = BuildChannel("pick_first", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // Wait for connect, which should fail ~immediately, because the server // is not up. gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT"); @@ -628,21 +660,22 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); std::vector ports; // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [0] *******"); CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 1); // An empty update will result in the channel going into TRANSIENT_FAILURE. ports.clear(); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET none *******"); grpc_connectivity_state channel_state; do { @@ -654,7 +687,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { // Next update introduces servers_[1], making the channel recover. ports.clear(); ports.emplace_back(servers_[1]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [1] *******"); WaitForServer(stub, 1, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 0); @@ -662,7 +695,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdates) { // And again for servers_[2] ports.clear(); ports.emplace_back(servers_[2]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [2] *******"); WaitForServer(stub, 2, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 0); @@ -676,14 +709,15 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); std::vector ports; // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET [0] *******"); CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(servers_[0]->service_.request_count(), 1); @@ -693,7 +727,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { ports.clear(); ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[0]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** SET superset *******"); CheckRpcSendOk(stub, DEBUG_LOCATION); // We stick to the previously connected server. @@ -710,12 +744,14 @@ TEST_F(ClientLbEnd2endTest, PickFirstGlobalSubchannelPool) { StartServers(kNumServers); std::vector ports = GetServersPorts(); // Create two channels that (by default) use the global subchannel pool. - auto channel1 = BuildChannel("pick_first"); + auto response_generator1 = BuildResolverResponseGenerator(); + auto channel1 = BuildChannel("pick_first", response_generator1); auto stub1 = BuildStub(channel1); - SetNextResolution(ports); - auto channel2 = BuildChannel("pick_first"); + response_generator1.SetNextResolution(ports); + auto response_generator2 = BuildResolverResponseGenerator(); + auto channel2 = BuildChannel("pick_first", response_generator2); auto stub2 = BuildStub(channel2); - SetNextResolution(ports); + response_generator2.SetNextResolution(ports); WaitForServer(stub1, 0, DEBUG_LOCATION); // Send one RPC on each channel. CheckRpcSendOk(stub1, DEBUG_LOCATION); @@ -735,12 +771,14 @@ TEST_F(ClientLbEnd2endTest, PickFirstLocalSubchannelPool) { // Create two channels that use local subchannel pool. ChannelArguments args; args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto channel1 = BuildChannel("pick_first", args); + auto response_generator1 = BuildResolverResponseGenerator(); + auto channel1 = BuildChannel("pick_first", response_generator1, args); auto stub1 = BuildStub(channel1); - SetNextResolution(ports); - auto channel2 = BuildChannel("pick_first", args); + response_generator1.SetNextResolution(ports); + auto response_generator2 = BuildResolverResponseGenerator(); + auto channel2 = BuildChannel("pick_first", response_generator2, args); auto stub2 = BuildStub(channel2); - SetNextResolution(ports); + response_generator2.SetNextResolution(ports); WaitForServer(stub1, 0, DEBUG_LOCATION); // Send one RPC on each channel. CheckRpcSendOk(stub1, DEBUG_LOCATION); @@ -756,13 +794,14 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { const int kNumUpdates = 1000; const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); std::vector ports = GetServersPorts(); for (size_t i = 0; i < kNumUpdates; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // We should re-enter core at the end of the loop to give the resolution // setting closure a chance to run. if ((i + 1) % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -784,16 +823,17 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { dead_ports.emplace_back(grpc_pick_unused_port_or_die()); } } - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); // The initial resolution only contains dead ports. There won't be any // selected subchannel. Re-resolution will return the same result. - SetNextResolution(dead_ports); + response_generator.SetNextResolution(dead_ports); gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******"); for (size_t i = 0; i < 10; ++i) CheckRpcSendFailure(stub); // Set a re-resolution result that contains reachable ports, so that the // pick_first LB policy can recover soon. - SetNextResolutionUponError(alive_ports); + response_generator.SetNextResolutionUponError(alive_ports); gpr_log(GPR_INFO, "****** RE-RESOLUTION SET *******"); WaitForServer(stub, 0, DEBUG_LOCATION, true /* ignore_failure */); CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -805,9 +845,10 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { TEST_F(ClientLbEnd2endTest, PickFirstReconnectWithoutNewResolverResult) { std::vector ports = {grpc_pick_unused_port_or_die()}; StartServers(1, ports); - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); WaitForServer(stub, 0, DEBUG_LOCATION); gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); @@ -824,9 +865,10 @@ TEST_F(ClientLbEnd2endTest, grpc_pick_unused_port_or_die()}; CreateServers(2, ports); StartServer(1); - auto channel = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); WaitForServer(stub, 1, DEBUG_LOCATION); gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); @@ -840,9 +882,10 @@ TEST_F(ClientLbEnd2endTest, TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { std::vector ports = {grpc_pick_unused_port_or_die()}; StartServers(1, ports); - auto channel_1 = BuildChannel("pick_first"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel_1 = BuildChannel("pick_first", response_generator); auto stub_1 = BuildStub(channel_1); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); WaitForServer(stub_1, 0, DEBUG_LOCATION); gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); @@ -851,13 +894,10 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { // create a new subchannel and hold a ref to it. StartServers(1, ports); gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); - auto channel_2 = BuildChannel("pick_first"); + auto response_generator_2 = BuildResolverResponseGenerator(); + auto channel_2 = BuildChannel("pick_first", response_generator_2); auto stub_2 = BuildStub(channel_2); - // TODO(juanlishen): This resolution result will only be visible to channel 2 - // since the response generator is only associated with channel 2 now. We - // should change the response generator to be able to deliver updates to - // multiple channels at once. - SetNextResolution(ports); + response_generator_2.SetNextResolution(ports); gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); WaitForServer(stub_2, 0, DEBUG_LOCATION, true); gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); @@ -883,13 +923,15 @@ TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { // Start server, send RPC, and make sure channel is READY. const int kNumServers = 1; StartServers(kNumServers); - auto channel = BuildChannel(""); // pick_first is the default. + auto response_generator = BuildResolverResponseGenerator(); + auto channel = + BuildChannel("", response_generator); // pick_first is the default. auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); // Stop server. Channel should go into state IDLE. - SetFailureOnReresolution(); + response_generator.SetFailureOnReresolution(); servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); @@ -897,14 +939,16 @@ TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { } TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { - auto channel = BuildChannel(""); // pick_first is the default. + auto response_generator = BuildResolverResponseGenerator(); + auto channel = + BuildChannel("", response_generator); // pick_first is the default. auto stub = BuildStub(channel); // Create a number of servers, but only start 1 of them. CreateServers(10); StartServer(0); // Initially resolve to first server and make sure it connects. gpr_log(GPR_INFO, "Phase 1: Connect to first server."); - SetNextResolution({servers_[0]->port_}); + response_generator.SetNextResolution({servers_[0]->port_}); CheckRpcSendOk(stub, DEBUG_LOCATION, true /* wait_for_ready */); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); // Send a resolution update with the remaining servers, none of which are @@ -916,7 +960,7 @@ TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { gpr_log(GPR_INFO, "Phase 2: Resolver update pointing to remaining " "(not started) servers."); - SetNextResolution(GetServersPorts(1 /* start_index */)); + response_generator.SetNextResolution(GetServersPorts(1 /* start_index */)); // RPCs will continue to be sent to the first server. CheckRpcSendOk(stub, DEBUG_LOCATION); // Now stop the first server, so that the current subchannel list @@ -947,9 +991,11 @@ TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { // Start server, send RPC, and make sure channel is READY. const int kNumServers = 1; StartServers(kNumServers); - auto channel = BuildChannel(""); // pick_first is the default. + auto response_generator = BuildResolverResponseGenerator(); + auto channel = + BuildChannel("", response_generator); // pick_first is the default. auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); // Stop server. Channel should go into state IDLE. @@ -958,13 +1004,13 @@ TEST_F(ClientLbEnd2endTest, PickFirstStaysIdleUponEmptyUpdate) { EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); // Now send resolver update that includes no addresses. Channel // should stay in state IDLE. - SetNextResolution({}); + response_generator.SetNextResolution({}); EXPECT_FALSE(channel->WaitForStateChange( GRPC_CHANNEL_IDLE, grpc_timeout_seconds_to_deadline(3))); // Now bring the backend back up and send a non-empty resolver update, // and then try to send an RPC. Channel should go back into state READY. StartServer(0); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); } @@ -973,9 +1019,10 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); // Wait until all backends are ready. do { CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -999,18 +1046,20 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { TEST_F(ClientLbEnd2endTest, RoundRobinProcessPending) { StartServers(1); // Single server - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - SetNextResolution({servers_[0]->port_}); + response_generator.SetNextResolution({servers_[0]->port_}); WaitForServer(stub, 0, DEBUG_LOCATION); // Create a new channel and its corresponding RR LB policy, which will pick // the subchannels in READY state from the previous RPC against the same // target (even if it happened over a different channel, because subchannels // are globally reused). Progress should happen without any transition from // this READY state. - auto second_channel = BuildChannel("round_robin"); + auto second_response_generator = BuildResolverResponseGenerator(); + auto second_channel = BuildChannel("round_robin", second_response_generator); auto second_stub = BuildStub(second_channel); - SetNextResolution({servers_[0]->port_}); + second_response_generator.SetNextResolution({servers_[0]->port_}); CheckRpcSendOk(second_stub, DEBUG_LOCATION); } @@ -1018,13 +1067,14 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); std::vector ports; // Start with a single server. gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); ports.emplace_back(servers_[0]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); // Send RPCs. They should all go servers_[0] for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -1036,7 +1086,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); // Wait until update has been processed, as signaled by the second backend // receiving a request. EXPECT_EQ(0, servers_[1]->service_.request_count()); @@ -1050,7 +1100,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); ports.clear(); ports.emplace_back(servers_[2]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 2, DEBUG_LOCATION); for (size_t i = 0; i < 10; ++i) CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_EQ(0, servers_[0]->service_.request_count()); @@ -1063,7 +1113,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { ports.emplace_back(servers_[0]->port_); ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); WaitForServer(stub, 1, DEBUG_LOCATION); WaitForServer(stub, 2, DEBUG_LOCATION); @@ -1075,7 +1125,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { // An empty update will result in the channel going into TRANSIENT_FAILURE. gpr_log(GPR_INFO, "*** NO BACKENDS ***"); ports.clear(); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); grpc_connectivity_state channel_state; do { channel_state = channel->GetState(true /* try to connect */); @@ -1086,7 +1136,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); ports.clear(); ports.emplace_back(servers_[1]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 1, DEBUG_LOCATION); channel_state = channel->GetState(false /* try to connect */); ASSERT_EQ(channel_state, GRPC_CHANNEL_READY); @@ -1097,13 +1147,14 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdates) { TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); std::vector ports; // Start with a single server. ports.emplace_back(servers_[0]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); // Send RPCs. They should all go to servers_[0] for (size_t i = 0; i < 10; ++i) SendRpc(stub); @@ -1116,7 +1167,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) { servers_[1]->Shutdown(); ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[2]->port_); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); WaitForServer(stub, 0, DEBUG_LOCATION); WaitForServer(stub, 2, DEBUG_LOCATION); @@ -1130,13 +1181,14 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); std::vector ports = GetServersPorts(); for (size_t i = 0; i < 1000; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. @@ -1162,9 +1214,10 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { second_ports.push_back(grpc_pick_unused_port_or_die()); } StartServers(kNumServers, first_ports); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - SetNextResolution(first_ports); + response_generator.SetNextResolution(first_ports); // Send a number of RPCs, which succeed. for (size_t i = 0; i < 100; ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -1188,7 +1241,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { StartServers(kNumServers, second_ports); // Don't notify of the update. Wait for the LB policy's re-resolution to // "pull" the new ports. - SetNextResolutionUponError(second_ports); + response_generator.SetNextResolutionUponError(second_ports); gpr_log(GPR_INFO, "****** SERVERS RESTARTED *******"); gpr_log(GPR_INFO, "****** SENDING REQUEST TO SUCCEED *******"); // Client request should eventually (but still fairly soon) succeed. @@ -1205,9 +1258,10 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { const int kNumServers = 3; StartServers(kNumServers); const auto ports = GetServersPorts(); - auto channel = BuildChannel("round_robin"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - SetNextResolution(ports); + response_generator.SetNextResolution(ports); for (size_t i = 0; i < kNumServers; ++i) { WaitForServer(stub, i, DEBUG_LOCATION); } @@ -1251,9 +1305,10 @@ TEST_F(ClientLbEnd2endTest, args.SetServiceConfigJSON( "{\"healthCheckConfig\": " "{\"serviceName\": \"health_check_service_name\"}}"); - auto channel = BuildChannel("round_robin", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution({servers_[0]->port_}); + response_generator.SetNextResolution({servers_[0]->port_}); EXPECT_TRUE(WaitForChannelReady(channel.get())); CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -1267,9 +1322,10 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { args.SetServiceConfigJSON( "{\"healthCheckConfig\": " "{\"serviceName\": \"health_check_service_name\"}}"); - auto channel = BuildChannel("round_robin", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = BuildChannel("round_robin", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); // Channel should not become READY, because health checks should be failing. gpr_log(GPR_INFO, "*** initial state: unknown health check service name for " @@ -1341,15 +1397,17 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { args.SetServiceConfigJSON( "{\"healthCheckConfig\": " "{\"serviceName\": \"health_check_service_name\"}}"); - auto channel1 = BuildChannel("round_robin", args); + auto response_generator1 = BuildResolverResponseGenerator(); + auto channel1 = BuildChannel("round_robin", response_generator1, args); auto stub1 = BuildStub(channel1); std::vector ports = GetServersPorts(); - SetNextResolution(ports); + response_generator1.SetNextResolution(ports); // Create a channel with health checking enabled but inhibited. args.SetInt(GRPC_ARG_INHIBIT_HEALTH_CHECKING, 1); - auto channel2 = BuildChannel("round_robin", args); + auto response_generator2 = BuildResolverResponseGenerator(); + auto channel2 = BuildChannel("round_robin", response_generator2, args); auto stub2 = BuildStub(channel2); - SetNextResolution(ports); + response_generator2.SetNextResolution(ports); // First channel should not become READY, because health checks should be // failing. EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); @@ -1376,19 +1434,21 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingServiceNamePerChannel) { args.SetServiceConfigJSON( "{\"healthCheckConfig\": " "{\"serviceName\": \"health_check_service_name\"}}"); - auto channel1 = BuildChannel("round_robin", args); + auto response_generator1 = BuildResolverResponseGenerator(); + auto channel1 = BuildChannel("round_robin", response_generator1, args); auto stub1 = BuildStub(channel1); std::vector ports = GetServersPorts(); - SetNextResolution(ports); + response_generator1.SetNextResolution(ports); // Create a channel with health-checking enabled with a different // service name. ChannelArguments args2; args2.SetServiceConfigJSON( "{\"healthCheckConfig\": " "{\"serviceName\": \"health_check_service_name2\"}}"); - auto channel2 = BuildChannel("round_robin", args2); + auto response_generator2 = BuildResolverResponseGenerator(); + auto channel2 = BuildChannel("round_robin", response_generator2, args2); auto stub2 = BuildStub(channel2); - SetNextResolution(ports); + response_generator2.SetNextResolution(ports); // Allow health checks from channel 2 to succeed. servers_[0]->SetServingStatus("health_check_service_name2", true); // First channel should not become READY, because health checks should be @@ -1438,9 +1498,11 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { const int kNumServers = 1; const int kNumRpcs = 10; StartServers(kNumServers); - auto channel = BuildChannel("intercept_trailing_metadata_lb"); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = + BuildChannel("intercept_trailing_metadata_lb", response_generator); auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); for (size_t i = 0; i < kNumRpcs; ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -1470,9 +1532,11 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { " }\n" " } ]\n" "}"); - auto channel = BuildChannel("intercept_trailing_metadata_lb", args); + auto response_generator = BuildResolverResponseGenerator(); + auto channel = + BuildChannel("intercept_trailing_metadata_lb", response_generator, args); auto stub = BuildStub(channel); - SetNextResolution(GetServersPorts()); + response_generator.SetNextResolution(GetServersPorts()); for (size_t i = 0; i < kNumRpcs; ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } From 648c5ff8a7685b9858ab498fc67a173c0dc22312 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 8 Jul 2019 12:35:11 -0700 Subject: [PATCH 602/676] Convert compile-time bool into template param in slicebuf --- src/core/lib/slice/slice_buffer.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 2b69f576a3c..7eedad3f379 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -262,9 +262,9 @@ void grpc_slice_buffer_move_into(grpc_slice_buffer* src, src->length = 0; } +template static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer* src, size_t n, - grpc_slice_buffer* dst, - bool incref) { + grpc_slice_buffer* dst) { GPR_ASSERT(src->length >= n); if (src->length == n) { grpc_slice_buffer_move_into(src, dst); @@ -304,12 +304,12 @@ static void slice_buffer_move_first_maybe_ref(grpc_slice_buffer* src, size_t n, void grpc_slice_buffer_move_first(grpc_slice_buffer* src, size_t n, grpc_slice_buffer* dst) { - slice_buffer_move_first_maybe_ref(src, n, dst, true); + slice_buffer_move_first_maybe_ref(src, n, dst); } void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer* src, size_t n, grpc_slice_buffer* dst) { - slice_buffer_move_first_maybe_ref(src, n, dst, false); + slice_buffer_move_first_maybe_ref(src, n, dst); } void grpc_slice_buffer_move_first_into_buffer(grpc_slice_buffer* src, size_t n, From 6518c2c67d4395e3676f841bcad5c00cdaf35e84 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 9 Jul 2019 10:05:10 -0700 Subject: [PATCH 603/676] Remove ThreadPoolWorker GABC --- src/core/lib/iomgr/executor/threadpool.cc | 2 +- src/core/lib/iomgr/executor/threadpool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index 82b1724c23a..deeadc0f758 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -99,7 +99,7 @@ ThreadPool::ThreadPool(int num_threads, const char* thd_name, } ThreadPool::~ThreadPool() { - shut_down_.Store(false, MemoryOrder::RELEASE); + shut_down_.Store(true, MemoryOrder::RELEASE); for (int i = 0; i < num_threads_; ++i) { queue_->Put(nullptr); diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index 3bc79aa6c3c..f0c54104ef1 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -79,7 +79,7 @@ class ThreadPoolWorker { void Start() { thd_.Start(); } void Join() { thd_.Join(); } - GRPC_ABSTRACT_BASE_CLASS + // GRPC_ABSTRACT_BASE_CLASS private: // struct for tracking stats of thread From 53b75d8c921cc80431802fe45f74699fa72c4829 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 9 Jul 2019 11:54:41 -0700 Subject: [PATCH 604/676] Change Get() signature, modify shut_down assertion & memoryorder --- src/core/lib/iomgr/executor/mpmcqueue.cc | 23 +++++++------------ src/core/lib/iomgr/executor/mpmcqueue.h | 12 +++++----- src/core/lib/iomgr/executor/threadpool.cc | 27 +++++++++++------------ src/core/lib/iomgr/executor/threadpool.h | 5 +++-- test/core/iomgr/threadpool_test.cc | 15 +++++-------- 5 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.cc b/src/core/lib/iomgr/executor/mpmcqueue.cc index 581045245c4..7f916258b82 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.cc +++ b/src/core/lib/iomgr/executor/mpmcqueue.cc @@ -98,32 +98,25 @@ void InfLenFIFOQueue::Put(void* elem) { } } -void* InfLenFIFOQueue::Get() { - MutexLock l(&mu_); - if (count_.Load(MemoryOrder::RELAXED) == 0) { - num_waiters_++; - do { - wait_nonempty_.Wait(&mu_); - } while (count_.Load(MemoryOrder::RELAXED) == 0); - num_waiters_--; - } - GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); - return PopFront(); -} - void* InfLenFIFOQueue::Get(gpr_timespec* wait_time) { MutexLock l(&mu_); if (count_.Load(MemoryOrder::RELAXED) == 0) { gpr_timespec start_time; - start_time = gpr_now(GPR_CLOCK_MONOTONIC); + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace) && + wait_time != nullptr) { + start_time = gpr_now(GPR_CLOCK_MONOTONIC); + } num_waiters_++; do { wait_nonempty_.Wait(&mu_); } while (count_.Load(MemoryOrder::RELAXED) == 0); num_waiters_--; - *wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), start_time); + if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace) && + wait_time != nullptr) { + *wait_time = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), start_time); + } } GPR_DEBUG_ASSERT(count_.Load(MemoryOrder::RELAXED) > 0); return PopFront(); diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index fdb3de00e73..5c62221e9d4 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -42,7 +42,8 @@ class MPMCQueueInterface { // Removes the oldest element from the queue and return it. // This might cause to block on empty queue depending on implementation. - virtual void* Get() GRPC_ABSTRACT; + // Optional argument for collecting stats purpose. + virtual void* Get(gpr_timespec* wait_time = nullptr) GRPC_ABSTRACT; // Returns number of elements in the queue currently virtual int count() const GRPC_ABSTRACT; @@ -65,12 +66,9 @@ class InfLenFIFOQueue : public MPMCQueueInterface { // Removes the oldest element from the queue and returns it. // This routine will cause the thread to block if queue is currently empty. - void* Get(); - - // Same as Get(), but will record how long waited when getting. - // This routine should be only called when debug trace is on and wants to - // collect stats data. - void* Get(gpr_timespec* wait_time); + // Argument wait_time should be passed in when trace flag turning on (for + // collecting stats info purpose.) + void* Get(gpr_timespec* wait_time = nullptr); // Returns number of elements in queue currently. // There might be concurrently add/remove on queue, so count might change diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index deeadc0f758..166bf0a34a0 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -29,21 +29,21 @@ void ThreadPoolWorker::Run() { if (GRPC_TRACE_FLAG_ENABLED(grpc_thread_pool_trace)) { // Updates stats and print gpr_timespec wait_time = gpr_time_0(GPR_TIMESPAN); - elem = static_cast(queue_)->Get(&wait_time); - stats_.sleep_cycles = gpr_time_add(stats_.sleep_cycles, wait_time); + elem = queue_->Get(&wait_time); + stats_.sleep_time = gpr_time_add(stats_.sleep_time, wait_time); gpr_log(GPR_INFO, - "ThreadPool Worker [%s %d] Stats: sleep_cycles %f", - thd_name_, index_, gpr_timespec_to_micros(stats_.sleep_cycles)); + "ThreadPool Worker [%s %d] Stats: sleep_time %f", + thd_name_, index_, gpr_timespec_to_micros(stats_.sleep_time)); } else { - elem = static_cast(queue_)->Get(); + elem = queue_->Get(nullptr); } if (elem == nullptr) { break; } // Runs closure - grpc_experimental_completion_queue_functor* closure = + auto* closure = static_cast(elem); - closure->functor_run(closure->internal_next, closure->internal_success); + closure->functor_run(closure, closure->internal_success); } } @@ -70,7 +70,8 @@ size_t ThreadPool::DefaultStackSize() { } bool ThreadPool::HasBeenShutDown() { - return shut_down_.Load(MemoryOrder::ACQUIRE); + // For debug checking purpose, using RELAXED order is sufficient. + return shut_down_.Load(MemoryOrder::RELAXED); } ThreadPool::ThreadPool(int num_threads) : num_threads_(num_threads) { @@ -99,7 +100,8 @@ ThreadPool::ThreadPool(int num_threads, const char* thd_name, } ThreadPool::~ThreadPool() { - shut_down_.Store(true, MemoryOrder::RELEASE); + // For debug checking purpose, using RELAXED order is sufficient. + shut_down_.Store(true, MemoryOrder::RELAXED); for (int i = 0; i < num_threads_; ++i) { queue_->Put(nullptr); @@ -117,11 +119,8 @@ ThreadPool::~ThreadPool() { } void ThreadPool::Add(grpc_experimental_completion_queue_functor* closure) { - if (HasBeenShutDown()) { - gpr_log(GPR_ERROR, "ThreadPool Has Already Been Shut Down."); - } else { - queue_->Put(static_cast(closure)); - } + GPR_DEBUG_ASSERT(!HasBeenShutDown()); + queue_->Put(static_cast(closure)); } int ThreadPool::num_pending_closures() const { return queue_->count(); } diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index f0c54104ef1..d68cbbf7328 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -84,8 +84,8 @@ class ThreadPoolWorker { private: // struct for tracking stats of thread struct Stats { - gpr_timespec sleep_cycles; - Stats() { sleep_cycles = gpr_time_0(GPR_TIMESPAN); } + gpr_timespec sleep_time; + Stats() { sleep_time = gpr_time_0(GPR_TIMESPAN); } }; void Run(); // Pulls closures from queue and executes them @@ -145,6 +145,7 @@ class ThreadPool : public ThreadPoolInterface { // For ThreadPool, default stack size for mobile platform is 1952K. for other // platforms is 64K. size_t DefaultStackSize(); + // Internal Use Only for debug checking. bool HasBeenShutDown(); }; diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index a56db5b647a..c093c421b7b 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -25,8 +25,6 @@ #define THREAD_SMALL_ITERATION 100 #define THREAD_LARGE_ITERATION 10000 -grpc_core::Mutex mu; - // Simple functor for testing. It will count how many times being called. class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { public: @@ -40,17 +38,15 @@ class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { static void Run(struct grpc_experimental_completion_queue_functor* cb, int ok) { auto* callback = static_cast(cb); - grpc_core::MutexLock l(&mu); - callback->count_++; + callback->count_.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); } int count() { - grpc_core::MutexLock l(&mu); - return count_; + return count_.Load(grpc_core::MemoryOrder::RELAXED); } private: - int count_; + grpc_core::Atomic count_{0}; }; // Checks the given SimpleFunctorForAdd's count with a given number. @@ -66,8 +62,9 @@ class SimpleFunctorCheckForAdd ~SimpleFunctorCheckForAdd() {} static void Run(struct grpc_experimental_completion_queue_functor* cb, int ok) { - auto* callback = static_cast(cb); - GPR_ASSERT(callback->count_ == ok); + auto* callback = static_cast(cb); + auto* cb_check = static_cast(callback->internal_next); + GPR_ASSERT(cb_check->count_.Load(grpc_core::MemoryOrder::RELAXED) == ok); } }; From 7bc9aba863250d15b00cd6aae4e4db231edb00ad Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 9 Jul 2019 12:13:33 -0700 Subject: [PATCH 605/676] Reformat --- test/core/iomgr/threadpool_test.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index c093c421b7b..e0a9d73f48b 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -41,9 +41,7 @@ class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { callback->count_.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); } - int count() { - return count_.Load(grpc_core::MemoryOrder::RELAXED); - } + int count() { return count_.Load(grpc_core::MemoryOrder::RELAXED); } private: grpc_core::Atomic count_{0}; From 11e60b8f30ca0bc77f6cec284806c5be2a33087b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 9 Jul 2019 16:50:53 -0700 Subject: [PATCH 606/676] Add documentation for compression enums --- src/python/grpcio/grpc/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index f0c198db66d..ac5192e0fed 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -1856,10 +1856,16 @@ def _create_servicer_context(rpc_event, state, request_deserializer): context._finalize_state() # pylint: disable=protected-access +@enum.unique class Compression(enum.IntEnum): """Indicates the compression method to be used for an RPC. This enumeration is part of an EXPERIMENTAL API. + + Attributes: + NoCompression: Do not use compression algorithm. + Deflate: Use "Deflate" compression algorithm. + Gzip: Use "Gzip" compression algorithm. """ NoCompression = _compression.NoCompression Deflate = _compression.Deflate From 51f80abb5a80f7b2666b88306740751ea90ca98e Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 13 Jun 2019 17:09:53 -0700 Subject: [PATCH 607/676] Coalesced some grpc_slice_buffer_tiny_add calls in hpack_enc --- .../chttp2/transport/hpack_encoder.cc | 28 +++++++++++-------- src/core/lib/slice/slice_buffer.cc | 3 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 666d28975a8..2b40b7b03ed 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -381,10 +381,11 @@ static void emit_lithdr_incidx(grpc_chttp2_hpack_compressor* c, uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); - GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, - add_tiny_header_data(st, len_pfx), len_pfx); + GPR_DEBUG_ASSERT(len_pfx + len_val_len < GRPC_SLICE_INLINED_SIZE); + uint8_t* data = add_tiny_header_data(st, len_pfx + len_val_len); + GRPC_CHTTP2_WRITE_VARINT(key_index, 2, 0x40, data, len_pfx); GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); + &data[len_pfx], len_val_len); add_wire_value(st, value); } @@ -398,10 +399,11 @@ static void emit_lithdr_noidx(grpc_chttp2_hpack_compressor* c, uint32_t len_val_len; GPR_ASSERT(len_val <= UINT32_MAX); len_val_len = GRPC_CHTTP2_VARINT_LENGTH((uint32_t)len_val, 1); - GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, - add_tiny_header_data(st, len_pfx), len_pfx); + GPR_DEBUG_ASSERT(len_pfx + len_val_len < GRPC_SLICE_INLINED_SIZE); + uint8_t* data = add_tiny_header_data(st, len_pfx + len_val_len); + GRPC_CHTTP2_WRITE_VARINT(key_index, 4, 0x00, data, len_pfx); GRPC_CHTTP2_WRITE_VARINT((uint32_t)len_val, 1, value.huffman_prefix, - add_tiny_header_data(st, len_val_len), len_val_len); + &data[len_pfx], len_val_len); add_wire_value(st, value); } @@ -418,9 +420,10 @@ static void emit_lithdr_incidx_v(grpc_chttp2_hpack_compressor* c, uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); GPR_ASSERT(len_key <= UINT32_MAX); GPR_ASSERT(wire_value_length(value) <= UINT32_MAX); - *add_tiny_header_data(st, 1) = 0x40; - GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, - add_tiny_header_data(st, len_key_len), len_key_len); + GPR_DEBUG_ASSERT(1 + len_key_len < GRPC_SLICE_INLINED_SIZE); + uint8_t* data = add_tiny_header_data(st, 1 + len_key_len); + data[0] = 0x40; + GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, &data[1], len_key_len); add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem))); GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); @@ -440,9 +443,10 @@ static void emit_lithdr_noidx_v(grpc_chttp2_hpack_compressor* c, uint32_t len_val_len = GRPC_CHTTP2_VARINT_LENGTH(len_val, 1); GPR_ASSERT(len_key <= UINT32_MAX); GPR_ASSERT(wire_value_length(value) <= UINT32_MAX); - *add_tiny_header_data(st, 1) = 0x00; - GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, - add_tiny_header_data(st, len_key_len), len_key_len); + /* Preconditions passed; emit header. */ + uint8_t* data = add_tiny_header_data(st, 1 + len_key_len); + data[0] = 0x00; + GRPC_CHTTP2_WRITE_VARINT(len_key, 1, 0x00, &data[1], len_key_len); add_header_data(st, grpc_slice_ref_internal(GRPC_MDKEY(elem))); GRPC_CHTTP2_WRITE_VARINT(len_val, 1, value.huffman_prefix, add_tiny_header_data(st, len_val_len), len_val_len); diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 2b69f576a3c..dfa4b84fd0f 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -103,7 +103,7 @@ uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t n) { sb->length += n; - if (sb->count == 0) goto add_new; + if (sb->count == 0) goto add_first; back = &sb->slices[sb->count - 1]; if (back->refcount) goto add_new; if ((back->data.inlined.length + n) > sizeof(back->data.inlined.bytes)) @@ -115,6 +115,7 @@ uint8_t* grpc_slice_buffer_tiny_add(grpc_slice_buffer* sb, size_t n) { add_new: maybe_embiggen(sb); +add_first: back = &sb->slices[sb->count]; sb->count++; back->refcount = nullptr; From 109edca9710ade3b67af6cf5a59cd48caf0da795 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Sun, 7 Jul 2019 22:44:33 -0700 Subject: [PATCH 608/676] Adding C++ API and implementation for STS credentials: - marked as experimental. - also changed the name of a field in the options struct. --- CMakeLists.txt | 75 +++++---- Makefile | 80 +++++---- build.yaml | 21 +-- include/grpc/grpc_security.h | 26 +-- include/grpcpp/security/credentials.h | 18 ++ include/grpcpp/security/credentials_impl.h | 64 +++++++ .../credentials/oauth2/oauth2_credentials.cc | 5 +- src/cpp/client/secure_credentials.cc | 148 +++++++++++++++++ src/cpp/client/secure_credentials.h | 11 ++ test/core/security/BUILD | 1 + test/core/security/fetch_oauth2.cc | 72 ++++---- test/cpp/client/credentials_test.cc | 157 ++++++++++++++++++ .../generated/sources_and_headers.json | 33 ++-- 13 files changed, 560 insertions(+), 151 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22c926df537..8dfa4e8009a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,7 +332,6 @@ add_dependencies(buildtests_c grpc_channel_stack_test) add_dependencies(buildtests_c grpc_completion_queue_test) add_dependencies(buildtests_c grpc_completion_queue_threading_test) add_dependencies(buildtests_c grpc_credentials_test) -add_dependencies(buildtests_c grpc_fetch_oauth2) add_dependencies(buildtests_c grpc_ipv6_loopback_available_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c grpc_json_token_test) @@ -634,6 +633,7 @@ add_dependencies(buildtests_cxx golden_file_test) add_dependencies(buildtests_cxx grpc_alts_credentials_options_test) add_dependencies(buildtests_cxx grpc_cli) add_dependencies(buildtests_cxx grpc_core_map_test) +add_dependencies(buildtests_cxx grpc_fetch_oauth2) add_dependencies(buildtests_cxx grpc_linux_system_roots_test) add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpclb_api_test) @@ -8270,40 +8270,6 @@ target_link_libraries(grpc_credentials_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(grpc_fetch_oauth2 - test/core/security/fetch_oauth2.cc -) - - -target_include_directories(grpc_fetch_oauth2 - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(grpc_fetch_oauth2 - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(grpc_fetch_oauth2 PROPERTIES LINKER_LANGUAGE C) - target_compile_options(grpc_fetch_oauth2 PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(grpc_ipv6_loopback_available_test test/core/iomgr/grpc_ipv6_loopback_available_test.cc ) @@ -14080,6 +14046,45 @@ endif() endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) +add_executable(grpc_fetch_oauth2 + test/core/security/fetch_oauth2.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(grpc_fetch_oauth2 + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpc_fetch_oauth2 + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(grpc_linux_system_roots_test test/core/security/linux_system_roots_test.cc third_party/googletest/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index c11462f419a..2a1bfad1f35 100644 --- a/Makefile +++ b/Makefile @@ -1056,7 +1056,6 @@ grpc_completion_queue_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_test grpc_completion_queue_threading_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test grpc_create_jwt: $(BINDIR)/$(CONFIG)/grpc_create_jwt grpc_credentials_test: $(BINDIR)/$(CONFIG)/grpc_credentials_test -grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 grpc_ipv6_loopback_available_test: $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test grpc_json_token_test: $(BINDIR)/$(CONFIG)/grpc_json_token_test grpc_jwt_verifier_test: $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test @@ -1219,6 +1218,7 @@ grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli grpc_core_map_test: $(BINDIR)/$(CONFIG)/grpc_core_map_test grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin +grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 grpc_linux_system_roots_test: $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin @@ -1489,7 +1489,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/grpc_completion_queue_test \ $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test \ $(BINDIR)/$(CONFIG)/grpc_credentials_test \ - $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \ $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test \ $(BINDIR)/$(CONFIG)/grpc_json_token_test \ $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \ @@ -1693,6 +1692,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ $(BINDIR)/$(CONFIG)/grpc_core_map_test \ + $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ @@ -1857,6 +1857,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ $(BINDIR)/$(CONFIG)/grpc_core_map_test \ + $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \ $(BINDIR)/$(CONFIG)/grpc_linux_system_roots_test \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ @@ -10987,38 +10988,6 @@ endif endif -GRPC_FETCH_OAUTH2_SRC = \ - test/core/security/fetch_oauth2.cc \ - -GRPC_FETCH_OAUTH2_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 - -endif - -$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) -endif -endif - - GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_SRC = \ test/core/iomgr/grpc_ipv6_loopback_available_test.cc \ @@ -17134,6 +17103,49 @@ ifneq ($(NO_DEPS),true) endif +GRPC_FETCH_OAUTH2_SRC = \ + test/core/security/fetch_oauth2.cc \ + +GRPC_FETCH_OAUTH2_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_FETCH_OAUTH2_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: 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.5.0+. + +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2: $(PROTOBUF_DEP) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_FETCH_OAUTH2_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/security/fetch_oauth2.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_grpc_fetch_oauth2: $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPC_FETCH_OAUTH2_OBJS:.o=.dep) +endif +endif + + GRPC_LINUX_SYSTEM_ROOTS_TEST_SRC = \ test/core/security/linux_system_roots_test.cc \ diff --git a/build.yaml b/build.yaml index 1c7be4e23ec..4134ecd8880 100644 --- a/build.yaml +++ b/build.yaml @@ -2863,16 +2863,6 @@ targets: - grpc_test_util - grpc - gpr -- name: grpc_fetch_oauth2 - build: test - run: false - language: c - src: - - test/core/security/fetch_oauth2.cc - deps: - - grpc_test_util - - grpc - - gpr - name: grpc_ipv6_loopback_available_test build: test language: c @@ -4945,6 +4935,17 @@ targets: deps: - grpc_plugin_support secure: false +- name: grpc_fetch_oauth2 + build: test + run: false + language: c++ + src: + - test/core/security/fetch_oauth2.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr - name: grpc_linux_system_roots_test gtest: true build: test diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 8e4f26a2854..777142f38c6 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -330,20 +330,20 @@ GRPCAPI grpc_call_credentials* grpc_google_iam_credentials_create( /** Options for creating STS Oauth Token Exchange credentials following the IETF draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16. - Optional fields may be set to NULL. It is the responsibility of the caller to - ensure that the subject and actor tokens are refreshed on disk at the - specified paths. This API is used for experimental purposes for now and may - change in the future. */ + Optional fields may be set to NULL or empty string. It is the responsibility + of the caller to ensure that the subject and actor tokens are refreshed on + disk at the specified paths. This API is used for experimental purposes for + now and may change in the future. */ typedef struct { - const char* sts_endpoint_url; /* Required. */ - const char* resource; /* Optional. */ - const char* audience; /* Optional. */ - const char* scope; /* Optional. */ - const char* requested_token_type; /* Optional. */ - const char* subject_token_path; /* Required. */ - const char* subject_token_type; /* Required. */ - const char* actor_token_path; /* Optional. */ - const char* actor_token_type; /* Optional. */ + const char* token_exchange_service_uri; /* Required. */ + const char* resource; /* Optional. */ + const char* audience; /* Optional. */ + const char* scope; /* Optional. */ + const char* requested_token_type; /* Optional. */ + const char* subject_token_path; /* Required. */ + const char* subject_token_type; /* Required. */ + const char* actor_token_path; /* Optional. */ + const char* actor_token_type; /* Optional. */ } grpc_sts_credentials_options; /** Creates an STS credentials following the STS Token Exchanged specifed in the diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index b124d3d37be..5190b1b3393 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -106,6 +106,24 @@ MetadataCredentialsFromPlugin( namespace experimental { +typedef ::grpc_impl::experimental::StsCredentialsOptions StsCredentialsOptions; + +static inline grpc::Status StsCredentialsOptionsFromJson( + const grpc::string& json_string, StsCredentialsOptions* options) { + return ::grpc_impl::experimental::StsCredentialsOptionsFromJson(json_string, + options); +} + +static inline grpc::Status StsCredentialsOptionsFromEnv( + StsCredentialsOptions* options) { + return grpc_impl::experimental::StsCredentialsOptionsFromEnv(options); +} + +static inline std::shared_ptr StsCredentials( + const StsCredentialsOptions& options) { + return grpc_impl::experimental::StsCredentials(options); +} + typedef ::grpc_impl::experimental::AltsCredentialsOptions AltsCredentialsOptions; diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 34920a55bbe..e236512f43e 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -259,6 +259,70 @@ std::shared_ptr MetadataCredentialsFromPlugin( namespace experimental { +/// Options for creating STS Oauth Token Exchange credentials following the IETF +/// draft https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16. +/// Optional fields may be set to empty string. It is the responsibility of the +/// caller to ensure that the subject and actor tokens are refreshed on disk at +/// the specified paths. +struct StsCredentialsOptions { + grpc::string token_exchange_service_uri; // Required. + grpc::string resource; // Optional. + grpc::string audience; // Optional. + grpc::string scope; // Optional. + grpc::string requested_token_type; // Optional. + grpc::string subject_token_path; // Required. + grpc::string subject_token_type; // Required. + grpc::string actor_token_path; // Optional. + grpc::string actor_token_type; // Optional. +}; + +/// Creates STS Options from a JSON string. The JSON schema is as follows: +/// { +/// "title": "STS Credentials Config", +/// "type": "object", +/// "required": ["token_exchange_service_uri", "subject_token_path", +/// "subject_token_type"], +/// "properties": { +/// "token_exchange_service_uri": { +/// "type": "string" +/// }, +/// "resource": { +/// "type": "string" +/// }, +/// "audience": { +/// "type": "string" +/// }, +/// "scope": { +/// "type": "string" +/// }, +/// "requested_token_type": { +/// "type": "string" +/// }, +/// "subject_token_path": { +/// "type": "string" +/// }, +/// "subject_token_type": { +/// "type": "string" +/// }, +/// "actor_token_path" : { +/// "type": "string" +/// }, +/// "actor_token_type": { +/// "type": "string" +/// } +/// } +/// } +grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, + StsCredentialsOptions* options); + +/// Creates STS credentials options from the $STS_CREDENTIALS environment +/// variable. This environment variable points to the path of a JSON file +/// comforming to the schema described above. +grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options); + +std::shared_ptr StsCredentials( + const StsCredentialsOptions& options); + /// Options used to build AltsCredentials. struct AltsCredentialsOptions { /// service accounts of target endpoint that will be acceptable diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 06fa8bbdb4b..7a584835b96 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -18,6 +18,7 @@ #include +#include "src/core/lib/json/json.h" #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h" #include @@ -641,8 +642,8 @@ grpc_error* ValidateStsCredentialsOptions( *sts_url_out = nullptr; InlinedVector error_list; UniquePtr sts_url( - options->sts_endpoint_url != nullptr - ? grpc_uri_parse(options->sts_endpoint_url, false) + options->token_exchange_service_uri != nullptr + ? grpc_uri_parse(options->token_exchange_service_uri, false) : nullptr); if (sts_url == nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index d73b3e035c8..5de5a76194e 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -17,13 +17,23 @@ */ #include "src/cpp/client/secure_credentials.h" + +#include +#include #include #include #include +#include #include #include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/json/json.h" #include "src/core/lib/security/transport/auth_filters.h" +#include "src/core/lib/security/util/json_util.h" #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" @@ -105,6 +115,144 @@ std::shared_ptr SslCredentials( namespace experimental { +namespace { + +void ClearStsCredentialsOptions(StsCredentialsOptions* options) { + if (options == nullptr) return; + options->token_exchange_service_uri.clear(); + options->resource.clear(); + options->audience.clear(); + options->scope.clear(); + options->requested_token_type.clear(); + options->subject_token_path.clear(); + options->subject_token_type.clear(); + options->actor_token_path.clear(); + options->actor_token_type.clear(); +} + +} // namespace + +// Builds STS credentials options from JSON. +grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, + StsCredentialsOptions* options) { + struct GrpcJsonDeleter { + void operator()(grpc_json* json) { grpc_json_destroy(json); } + }; + if (options == nullptr) { + return grpc::Status(grpc::INVALID_ARGUMENT, "options cannot be nullptr."); + } + ClearStsCredentialsOptions(options); + std::vector scratchpad(json_string.c_str(), + json_string.c_str() + json_string.size() + 1); + std::unique_ptr json( + grpc_json_parse_string(&scratchpad[0])); + if (json == nullptr) { + return grpc::Status(grpc::INVALID_ARGUMENT, "Invalid json."); + } + + // Required fields. + const char* value = grpc_json_get_string_property( + json.get(), "token_exchange_service_uri", nullptr); + if (value == nullptr) { + ClearStsCredentialsOptions(options); + return grpc::Status(grpc::INVALID_ARGUMENT, + "token_exchange_service_uri must be specified."); + } + options->token_exchange_service_uri.assign(value); + value = + grpc_json_get_string_property(json.get(), "subject_token_path", nullptr); + if (value == nullptr) { + ClearStsCredentialsOptions(options); + return grpc::Status(grpc::INVALID_ARGUMENT, + "subject_token_path must be specified."); + } + options->subject_token_path.assign(value); + value = + grpc_json_get_string_property(json.get(), "subject_token_type", nullptr); + if (value == nullptr) { + ClearStsCredentialsOptions(options); + return grpc::Status(grpc::INVALID_ARGUMENT, + "subject_token_type must be specified."); + } + options->subject_token_type.assign(value); + + // Optional fields. + value = grpc_json_get_string_property(json.get(), "resource", nullptr); + if (value != nullptr) options->resource.assign(value); + value = grpc_json_get_string_property(json.get(), "audience", nullptr); + if (value != nullptr) options->audience.assign(value); + value = grpc_json_get_string_property(json.get(), "scope", nullptr); + if (value != nullptr) options->scope.assign(value); + value = grpc_json_get_string_property(json.get(), "requested_token_type", + nullptr); + if (value != nullptr) options->requested_token_type.assign(value); + value = + grpc_json_get_string_property(json.get(), "actor_token_path", nullptr); + if (value != nullptr) options->actor_token_path.assign(value); + value = + grpc_json_get_string_property(json.get(), "actor_token_type", nullptr); + if (value != nullptr) options->actor_token_type.assign(value); + + return grpc::Status(); +} + +// Builds STS credentials Options from the $STS_CREDENTIALS env var. +grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options) { + if (options == nullptr) { + return grpc::Status(grpc::INVALID_ARGUMENT, "options cannot be nullptr."); + } + ClearStsCredentialsOptions(options); + grpc_slice json_string = grpc_empty_slice(); + char* sts_creds_path = gpr_getenv("STS_CREDENTIALS"); + grpc_error* error = GRPC_ERROR_NONE; + grpc::Status status; + auto cleanup = [&json_string, &sts_creds_path, &error, &status]() { + grpc_slice_unref_internal(json_string); + gpr_free(sts_creds_path); + GRPC_ERROR_UNREF(error); + return status; + }; + + if (sts_creds_path == nullptr) { + status = grpc::Status(grpc::NOT_FOUND, + "STS_CREDENTIALS environment variable not set."); + return cleanup(); + } + error = grpc_load_file(sts_creds_path, 1, &json_string); + if (error != GRPC_ERROR_NONE) { + status = grpc::Status(grpc::NOT_FOUND, grpc_error_string(error)); + return cleanup(); + } + status = StsCredentialsOptionsFromJson( + reinterpret_cast(GRPC_SLICE_START_PTR(json_string)), + options); + return cleanup(); +} + +// C++ to Core STS Credentials options. +grpc_sts_credentials_options StsCredentialsCppToCoreOptions( + const StsCredentialsOptions& options) { + grpc_sts_credentials_options opts; + memset(&opts, 0, sizeof(opts)); + opts.token_exchange_service_uri = options.token_exchange_service_uri.c_str(); + opts.resource = options.resource.c_str(); + opts.audience = options.audience.c_str(); + opts.scope = options.scope.c_str(); + opts.requested_token_type = options.requested_token_type.c_str(); + opts.subject_token_path = options.subject_token_path.c_str(); + opts.subject_token_type = options.subject_token_type.c_str(); + opts.actor_token_path = options.actor_token_path.c_str(); + opts.actor_token_type = options.actor_token_type.c_str(); + return opts; +} + +// Builds STS credentials. +std::shared_ptr StsCredentials( + const StsCredentialsOptions& options) { + auto opts = StsCredentialsCppToCoreOptions(options); + return WrapCallCredentials(grpc_sts_credentials_create(&opts, nullptr)); +} + // Builds ALTS Credentials given ALTS specific options std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index dd379ca657d..ed14df4938e 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -22,6 +22,7 @@ #include #include +#include #include #include "src/core/lib/security/credentials/credentials.h" @@ -68,6 +69,16 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; +namespace experimental { + +// Transforms C++ STS Credentials options to core options. The pointers of the +// resulting core options point to the memory held by the C++ options so C++ +// options need to be kept alive until after the core credentials creation. +grpc_sts_credentials_options StsCredentialsCppToCoreOptions( + const StsCredentialsOptions& options); + +} // namespace experimental + } // namespace grpc_impl namespace grpc { diff --git a/test/core/security/BUILD b/test/core/security/BUILD index d8dcdc25231..835c0ad7b65 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -171,6 +171,7 @@ grpc_cc_binary( ":oauth2_utils", "//:gpr", "//:grpc", + "//:grpc++", "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/security/fetch_oauth2.cc b/test/core/security/fetch_oauth2.cc index d404368b8b9..1aa999758b0 100644 --- a/test/core/security/fetch_oauth2.cc +++ b/test/core/security/fetch_oauth2.cc @@ -26,53 +26,40 @@ #include #include +#include "grpcpp/security/credentials_impl.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/util/json_util.h" +#include "src/cpp/client/secure_credentials.h" #include "test/core/security/oauth2_utils.h" #include "test/core/util/cmdline.h" -static grpc_sts_credentials_options sts_options_from_json(grpc_json* json) { - grpc_sts_credentials_options options; - memset(&options, 0, sizeof(options)); - grpc_error* error = GRPC_ERROR_NONE; - options.sts_endpoint_url = - grpc_json_get_string_property(json, "sts_endpoint_url", &error); - GRPC_LOG_IF_ERROR("STS credentials parsing", error); - options.resource = grpc_json_get_string_property(json, "resource", nullptr); - options.audience = grpc_json_get_string_property(json, "audience", nullptr); - options.scope = grpc_json_get_string_property(json, "scope", nullptr); - options.requested_token_type = - grpc_json_get_string_property(json, "requested_token_type", nullptr); - options.subject_token_path = - grpc_json_get_string_property(json, "subject_token_path", &error); - GRPC_LOG_IF_ERROR("STS credentials parsing", error); - options.subject_token_type = - grpc_json_get_string_property(json, "subject_token_type", &error); - GRPC_LOG_IF_ERROR("STS credentials parsing", error); - options.actor_token_path = - grpc_json_get_string_property(json, "actor_token_path", nullptr); - options.actor_token_type = - grpc_json_get_string_property(json, "actor_token_type", nullptr); - return options; -} - static grpc_call_credentials* create_sts_creds(const char* json_file_path) { - grpc_slice sts_options_slice; - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "load_file", grpc_load_file(json_file_path, 1, &sts_options_slice))); - grpc_json* json = grpc_json_parse_string( - reinterpret_cast(GRPC_SLICE_START_PTR(sts_options_slice))); - if (json == nullptr) { - gpr_log(GPR_ERROR, "Invalid json"); - return nullptr; + grpc_impl::experimental::StsCredentialsOptions options; + if (strlen(json_file_path) == 0) { + auto status = + grpc_impl::experimental::StsCredentialsOptionsFromEnv(&options); + if (!status.ok()) { + gpr_log(GPR_ERROR, "%s", status.error_message().c_str()); + return nullptr; + } + } else { + grpc_slice sts_options_slice; + GPR_ASSERT(GRPC_LOG_IF_ERROR( + "load_file", grpc_load_file(json_file_path, 1, &sts_options_slice))); + auto status = grpc_impl::experimental::StsCredentialsOptionsFromJson( + reinterpret_cast(GRPC_SLICE_START_PTR(sts_options_slice)), + &options); + gpr_slice_unref(sts_options_slice); + if (!status.ok()) { + gpr_log(GPR_ERROR, "%s", status.error_message().c_str()); + return nullptr; + } } - grpc_sts_credentials_options options = sts_options_from_json(json); - grpc_call_credentials* result = - grpc_sts_credentials_create(&options, nullptr); - grpc_json_destroy(json); - gpr_slice_unref(sts_options_slice); + grpc_sts_credentials_options opts = + grpc_impl::experimental::StsCredentialsCppToCoreOptions(options); + grpc_call_credentials* result = grpc_sts_credentials_create(&opts, nullptr); return result; } @@ -99,9 +86,12 @@ int main(int argc, char** argv) { gpr_cmdline_add_string(cl, "json_refresh_token", "File path of the json refresh token.", &json_refresh_token_file_path); - gpr_cmdline_add_string(cl, "json_sts_options", - "File path of the json sts options.", - &json_sts_options_file_path); + gpr_cmdline_add_string( + cl, "json_sts_options", + "File path of the json sts options. If the path is empty, the program " + "will attempt to use the $STS_CREDENTIALS environment variable to access " + "a file containing the options.", + &json_sts_options_file_path); gpr_cmdline_add_flag( cl, "gce", "Get a token from the GCE metadata server (only works in GCE).", diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index e64e260a46c..d560fb6d8e8 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -20,9 +20,14 @@ #include +#include #include #include +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/tmpfile.h" +#include "src/cpp/client/secure_credentials.h" + namespace grpc { namespace testing { @@ -39,6 +44,158 @@ TEST_F(CredentialsTest, DefaultCredentials) { auto creds = GoogleDefaultCredentials(); } +TEST_F(CredentialsTest, StsCredentialsOptionsCppToCore) { + grpc::experimental::StsCredentialsOptions options; + options.token_exchange_service_uri = "https://foo.com/exchange"; + options.resource = "resource"; + options.audience = "audience"; + options.scope = "scope"; + // options.requested_token_type explicitly not set. + options.subject_token_path = "/foo/bar"; + options.subject_token_type = "nice_token_type"; + options.actor_token_path = "/foo/baz"; + options.actor_token_type = "even_nicer_token_type"; + grpc_sts_credentials_options core_opts = + grpc_impl::experimental::StsCredentialsCppToCoreOptions(options); + EXPECT_EQ(options.token_exchange_service_uri, + core_opts.token_exchange_service_uri); + EXPECT_EQ(options.resource, core_opts.resource); + EXPECT_EQ(options.audience, core_opts.audience); + EXPECT_EQ(options.scope, core_opts.scope); + EXPECT_EQ(options.requested_token_type, core_opts.requested_token_type); + EXPECT_EQ(options.subject_token_path, core_opts.subject_token_path); + EXPECT_EQ(options.subject_token_type, core_opts.subject_token_type); + EXPECT_EQ(options.actor_token_path, core_opts.actor_token_path); + EXPECT_EQ(options.actor_token_type, core_opts.actor_token_type); +} + +TEST_F(CredentialsTest, StsCredentialsOptionsJson) { + const char valid_json[] = R"( + { + "token_exchange_service_uri": "https://foo/exchange", + "resource": "resource", + "audience": "audience", + "scope": "scope", + "requested_token_type": "requested_token_type", + "subject_token_path": "subject_token_path", + "subject_token_type": "subject_token_type", + "actor_token_path": "actor_token_path", + "actor_token_type": "actor_token_type" + })"; + grpc::experimental::StsCredentialsOptions options; + EXPECT_TRUE( + grpc::experimental::StsCredentialsOptionsFromJson(valid_json, &options) + .ok()); + EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange"); + EXPECT_EQ(options.resource, "resource"); + EXPECT_EQ(options.audience, "audience"); + EXPECT_EQ(options.scope, "scope"); + EXPECT_EQ(options.requested_token_type, "requested_token_type"); + EXPECT_EQ(options.subject_token_path, "subject_token_path"); + EXPECT_EQ(options.subject_token_type, "subject_token_type"); + EXPECT_EQ(options.actor_token_path, "actor_token_path"); + EXPECT_EQ(options.actor_token_type, "actor_token_type"); + + const char minimum_valid_json[] = R"( + { + "token_exchange_service_uri": "https://foo/exchange", + "subject_token_path": "subject_token_path", + "subject_token_type": "subject_token_type" + })"; + EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson( + minimum_valid_json, &options) + .ok()); + EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange"); + EXPECT_EQ(options.resource, ""); + EXPECT_EQ(options.audience, ""); + EXPECT_EQ(options.scope, ""); + EXPECT_EQ(options.requested_token_type, ""); + EXPECT_EQ(options.subject_token_path, "subject_token_path"); + EXPECT_EQ(options.subject_token_type, "subject_token_type"); + EXPECT_EQ(options.actor_token_path, ""); + EXPECT_EQ(options.actor_token_type, ""); + + const char invalid_json[] = R"( + I'm not a valid JSON. + )"; + EXPECT_EQ( + grpc::INVALID_ARGUMENT, + grpc::experimental::StsCredentialsOptionsFromJson(invalid_json, &options) + .error_code()); + + const char invalid_json_missing_subject_token_type[] = R"( + { + "token_exchange_service_uri": "https://foo/exchange", + "subject_token_path": "subject_token_path" + })"; + auto status = grpc::experimental::StsCredentialsOptionsFromJson( + invalid_json_missing_subject_token_type, &options); + EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_THAT(status.error_message(), + ::testing::HasSubstr("subject_token_type")); + + const char invalid_json_missing_subject_token_path[] = R"( + { + "token_exchange_service_uri": "https://foo/exchange", + "subject_token_type": "subject_token_type" + })"; + status = grpc::experimental::StsCredentialsOptionsFromJson( + invalid_json_missing_subject_token_path, &options); + EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_THAT(status.error_message(), + ::testing::HasSubstr("subject_token_path")); + + const char invalid_json_missing_token_exchange_uri[] = R"( + { + "subject_token_path": "subject_token_path", + "subject_token_type": "subject_token_type" + })"; + status = grpc::experimental::StsCredentialsOptionsFromJson( + invalid_json_missing_token_exchange_uri, &options); + EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_THAT(status.error_message(), + ::testing::HasSubstr("token_exchange_service_uri")); +} + +TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) { + // Unset env and check expected failure. + gpr_unsetenv("STS_CREDENTIALS"); + grpc::experimental::StsCredentialsOptions options; + auto status = grpc::experimental::StsCredentialsOptionsFromEnv(&options); + EXPECT_EQ(grpc::NOT_FOUND, status.error_code()); + + // Set env and check for success. + const char valid_json[] = R"( + { + "token_exchange_service_uri": "https://foo/exchange", + "subject_token_path": "subject_token_path", + "subject_token_type": "subject_token_type" + })"; + char* creds_file_name; + FILE* creds_file = gpr_tmpfile("sts_creds_options", &creds_file_name); + ASSERT_NE(creds_file_name, nullptr); + ASSERT_NE(creds_file, nullptr); + ASSERT_EQ(sizeof(valid_json), + fwrite(valid_json, 1, sizeof(valid_json), creds_file)); + fclose(creds_file); + gpr_setenv("STS_CREDENTIALS", creds_file_name); + gpr_free(creds_file_name); + status = grpc::experimental::StsCredentialsOptionsFromEnv(&options); + EXPECT_TRUE(status.ok()); + EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange"); + EXPECT_EQ(options.resource, ""); + EXPECT_EQ(options.audience, ""); + EXPECT_EQ(options.scope, ""); + EXPECT_EQ(options.requested_token_type, ""); + EXPECT_EQ(options.subject_token_path, "subject_token_path"); + EXPECT_EQ(options.subject_token_type, "subject_token_type"); + EXPECT_EQ(options.actor_token_path, ""); + EXPECT_EQ(options.actor_token_type, ""); + + // Cleanup. + gpr_unsetenv("STS_CREDENTIALS"); +} + } // namespace testing } // namespace grpc diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 92b3757c65e..0f560fd1063 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1024,22 +1024,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "grpc_fetch_oauth2", - "src": [ - "test/core/security/fetch_oauth2.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -3878,6 +3862,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "grpc_fetch_oauth2", + "src": [ + "test/core/security/fetch_oauth2.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", From ee7b5be39649cee0b5b02a2f81a97794388a2c14 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 10 Jul 2019 04:35:30 -0400 Subject: [PATCH 609/676] more accurate comment --- src/csharp/Grpc.Core.Api/DeserializationContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/DeserializationContext.cs b/src/csharp/Grpc.Core.Api/DeserializationContext.cs index eb00f67601e..b0c3badbc24 100644 --- a/src/csharp/Grpc.Core.Api/DeserializationContext.cs +++ b/src/csharp/Grpc.Core.Api/DeserializationContext.cs @@ -53,7 +53,7 @@ namespace Grpc.Core /// The ReadOnlySequence is only valid for the duration of the deserializer routine and the caller must not access it after the deserializer returns. /// Using the read only sequence is the most efficient way to access the message payload. Where possible it allows directly /// accessing the received payload without needing to perform any buffer copying or buffer allocations. - /// NOTE: In order to access the payload via this method, your compiler needs to support C# 7.2 (to be able to use the Span type). + /// NOTE: When using this method, it is recommended to use C# 7.2 compiler to make it more useful (using Span type directly from your code requires C# 7.2)." /// NOTE: Deserializers are expected not to call this method (or other payload accessor methods) more than once per received message /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// From 578f027e3c6363d2e0b5d9679a90e36a4bc50e55 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 10 Jul 2019 04:43:05 -0400 Subject: [PATCH 610/676] deduplicate GUIDs in unity package skeleton --- .../unitypackage_skeleton/Plugins/System.Buffers/lib.meta | 2 +- .../unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta | 2 +- .../Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta | 2 +- .../Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta | 2 +- .../unitypackage_skeleton/Plugins/System.Memory/lib.meta | 2 +- .../unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta | 2 +- .../Plugins/System.Memory/lib/net45/System.Memory.dll.meta | 2 +- .../Plugins/System.Memory/lib/net45/System.Memory.xml.meta | 2 +- .../Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta | 2 +- .../System.Runtime.CompilerServices.Unsafe/lib/net45.meta | 2 +- .../lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta | 2 +- .../lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta index d7ae012a397..754fcaee5f1 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bd5ddd2522dc301488ffe002106fe0ab +guid: 0cb4be3dca2a49e6a920da037ea13d80 folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta index 9b1748d3e76..00368db2d4f 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a68443518bcd1d44ba88a871dcab0c83 +guid: 53b3f7a608814da5a3e3207d10c85b4e folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta index bb910fe9229..6a9eae1c5b8 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.dll.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +guid: bb037a236f584460af82c59c5d5ad972 timeCreated: 1531219386 licenseType: Free PluginImporter: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta index 53f91502bd6..14b3b367a4a 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Buffers/lib/net45/System.Buffers.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6fc38864f2d3dde46b3833c62c91a008 +guid: 4b9fff86d3b2471eb0003735b3ce3a51 timeCreated: 1531219386 licenseType: Free TextScriptImporter: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta index d7ae012a397..eab9851920f 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bd5ddd2522dc301488ffe002106fe0ab +guid: 3d6c20bf92b74c03b1ba691cbce610e4 folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta index 9b1748d3e76..2d33fd95298 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a68443518bcd1d44ba88a871dcab0c83 +guid: 7164a0a387b24d1a9d76f6d558fc44d2 folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta index bb910fe9229..11af5eae04c 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.dll.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +guid: e774d51b8ba64a988dd37135e487105c timeCreated: 1531219386 licenseType: Free PluginImporter: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta index 53f91502bd6..4c04cedb0eb 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Memory/lib/net45/System.Memory.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6fc38864f2d3dde46b3833c62c91a008 +guid: 3d27c5afe3114f67b0f6e27e36b89d5c timeCreated: 1531219386 licenseType: Free TextScriptImporter: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta index d7ae012a397..b3a382aed11 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: bd5ddd2522dc301488ffe002106fe0ab +guid: f51cc0f065424fb2928eee7c2804bfd8 folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta index 9b1748d3e76..4154241974e 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a68443518bcd1d44ba88a871dcab0c83 +guid: aad21c5c1f2f4c1391b1e4a475f163bb folderAsset: yes timeCreated: 1531219385 licenseType: Free diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta index bb910fe9229..c3988cadd4e 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.dll.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4c05e46cbf00c68408f5ddc1eef9ae3b +guid: d378b9cd266a4a448f071c114e5f18cb timeCreated: 1531219386 licenseType: Free PluginImporter: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta index 53f91502bd6..e756ced26d0 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Runtime.CompilerServices.Unsafe/lib/net45/System.Runtime.CompilerServices.Unsafe.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6fc38864f2d3dde46b3833c62c91a008 +guid: cfa8e546fee54a5ea3b20cf9dcf90fdf timeCreated: 1531219386 licenseType: Free TextScriptImporter: From 5dee89b06e3171ec1fee76245055106372d59e5b Mon Sep 17 00:00:00 2001 From: Wensheng Tang Date: Sun, 7 Jul 2019 01:59:28 +0800 Subject: [PATCH 611/676] Use grpc_error defs instead of NULL NULL is not clear for a grpc_error. Not sure we should use other error codes here. --- src/core/lib/iomgr/tcp_server_windows.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index abfa3be5708..0024f807ed3 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -409,7 +409,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, SOCKET sock, gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message); gpr_free(utf8_message); closesocket(sock); - return NULL; + return GRPC_ERROR_NONE; } error = prepare_socket(sock, addr, &port); From c01477360f148b67d7858b10ecb655aee2a24a31 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Wed, 3 Jul 2019 16:24:30 -0700 Subject: [PATCH 612/676] Add v1.22.0 to interop_matrix --- tools/interop_matrix/client_matrix.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index d6d0612b4e4..3f136b69bc2 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -98,6 +98,7 @@ LANG_RELEASE_MATRIX = { ('v1.19.0', ReleaseInfo(testcases_file='cxx__v1.0.1')), ('v1.20.0', ReleaseInfo()), ('v1.21.4', ReleaseInfo()), + ('v1.22.0', ReleaseInfo()), ]), 'go': OrderedDict( @@ -211,6 +212,7 @@ LANG_RELEASE_MATRIX = { ('v1.19.0', ReleaseInfo()), ('v1.20.0', ReleaseInfo()), ('v1.21.4', ReleaseInfo()), + ('v1.22.0', ReleaseInfo()), ]), 'node': OrderedDict([ @@ -260,6 +262,7 @@ LANG_RELEASE_MATRIX = { ('v1.19.0', ReleaseInfo()), ('v1.20.0', ReleaseInfo()), ('v1.21.4', ReleaseInfo()), + ('v1.22.0', ReleaseInfo()), # TODO: https://github.com/grpc/grpc/issues/18262. # If you are not encountering the error in above issue # go ahead and upload the docker image for new releases. @@ -287,6 +290,7 @@ LANG_RELEASE_MATRIX = { # v1.19 and v1.20 were deliberately omitted here because of an issue. # See https://github.com/grpc/grpc/issues/18264 ('v1.21.4', ReleaseInfo()), + ('v1.22.0', ReleaseInfo()), ]), 'csharp': OrderedDict([ @@ -317,5 +321,6 @@ LANG_RELEASE_MATRIX = { ('v1.19.0', ReleaseInfo(testcases_file='csharp__v1.18.0')), ('v1.20.0', ReleaseInfo()), ('v1.21.4', ReleaseInfo()), + ('v1.22.0', ReleaseInfo()), ]), } From bd5ed4fddd7e3aa9121a9eed92b820ef37e03b48 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Mon, 24 Jun 2019 16:37:08 -0700 Subject: [PATCH 613/676] Move compiler targets from /BUILD to /src/compiler/BUILD --- BUILD | 87 ------------- BUILD.gn | 1 + bazel/cc_grpc_library.bzl | 2 +- bazel/grpc_deps.bzl | 2 +- bazel/python_rules.bzl | 2 +- build.yaml | 1 + src/compiler/BUILD | 120 ++++++++++++++++++ src/compiler/config.h | 30 +---- src/compiler/config_protobuf.h | 52 ++++++++ .../generated/sources_and_headers.json | 2 + 10 files changed, 180 insertions(+), 119 deletions(-) create mode 100644 src/compiler/BUILD create mode 100644 src/compiler/config_protobuf.h diff --git a/BUILD b/BUILD index 95d8f753e39..b5d7761a9a1 100644 --- a/BUILD +++ b/BUILD @@ -30,7 +30,6 @@ load( "//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_generate_one_off_targets", - "grpc_proto_plugin", ) config_setting( @@ -429,92 +428,6 @@ grpc_cc_library( ], ) -grpc_cc_library( - name = "grpc_plugin_support", - srcs = [ - "src/compiler/cpp_generator.cc", - "src/compiler/csharp_generator.cc", - "src/compiler/node_generator.cc", - "src/compiler/objective_c_generator.cc", - "src/compiler/php_generator.cc", - "src/compiler/python_generator.cc", - "src/compiler/ruby_generator.cc", - ], - hdrs = [ - "src/compiler/config.h", - "src/compiler/cpp_generator.h", - "src/compiler/cpp_generator_helpers.h", - "src/compiler/cpp_plugin.h", - "src/compiler/csharp_generator.h", - "src/compiler/csharp_generator_helpers.h", - "src/compiler/generator_helpers.h", - "src/compiler/node_generator.h", - "src/compiler/node_generator_helpers.h", - "src/compiler/objective_c_generator.h", - "src/compiler/objective_c_generator_helpers.h", - "src/compiler/php_generator.h", - "src/compiler/php_generator_helpers.h", - "src/compiler/protobuf_plugin.h", - "src/compiler/python_generator.h", - "src/compiler/python_generator_helpers.h", - "src/compiler/python_private_generator.h", - "src/compiler/ruby_generator.h", - "src/compiler/ruby_generator_helpers-inl.h", - "src/compiler/ruby_generator_map-inl.h", - "src/compiler/ruby_generator_string-inl.h", - "src/compiler/schema_interface.h", - ], - external_deps = [ - "protobuf_clib", - ], - language = "c++", - deps = [ - "grpc++_config_proto", - ], -) - -grpc_proto_plugin( - name = "grpc_cpp_plugin", - srcs = ["src/compiler/cpp_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_csharp_plugin", - srcs = ["src/compiler/csharp_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_node_plugin", - srcs = ["src/compiler/node_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_objective_c_plugin", - srcs = ["src/compiler/objective_c_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_php_plugin", - srcs = ["src/compiler/php_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_python_plugin", - srcs = ["src/compiler/python_plugin.cc"], - deps = [":grpc_plugin_support"], -) - -grpc_proto_plugin( - name = "grpc_ruby_plugin", - srcs = ["src/compiler/ruby_plugin.cc"], - deps = [":grpc_plugin_support"], -) - grpc_cc_library( name = "grpc_csharp_ext", srcs = [ diff --git a/BUILD.gn b/BUILD.gn index 0868b2dae5a..177f4082adf 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1413,6 +1413,7 @@ config("grpc_config") { "include/grpc++/impl/codegen/config_protobuf.h", "include/grpcpp/impl/codegen/config_protobuf.h", "src/compiler/config.h", + "src/compiler/config_protobuf.h", "src/compiler/cpp_generator.cc", "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", diff --git a/bazel/cc_grpc_library.bzl b/bazel/cc_grpc_library.bzl index 572af756176..dea493eaf20 100644 --- a/bazel/cc_grpc_library.bzl +++ b/bazel/cc_grpc_library.bzl @@ -88,7 +88,7 @@ def cc_grpc_library( generate_cc( name = codegen_grpc_target, srcs = proto_targets, - plugin = "@com_github_grpc_grpc//:grpc_cpp_plugin", + plugin = "@com_github_grpc_grpc//src/compiler:grpc_cpp_plugin", well_known_protos = well_known_protos, generate_mocks = generate_mocks, **kwargs diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index be58c52b2b9..49def4f82c1 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -78,7 +78,7 @@ def grpc_deps(): native.bind( name = "grpc_cpp_plugin", - actual = "@com_github_grpc_grpc//:grpc_cpp_plugin", + actual = "@com_github_grpc_grpc//src/compiler:grpc_cpp_plugin", ) native.bind( diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl index d4ff77094cc..14550852a4a 100644 --- a/bazel/python_rules.bzl +++ b/bazel/python_rules.bzl @@ -163,7 +163,7 @@ def py_proto_library( _generate_py( name = codegen_grpc_target, deps = deps, - plugin = "//:grpc_python_plugin", + plugin = "//src/compiler:grpc_python_plugin", well_known_protos = well_known_protos, **kwargs ) diff --git a/build.yaml b/build.yaml index 4134ecd8880..5915b9ccd64 100644 --- a/build.yaml +++ b/build.yaml @@ -1969,6 +1969,7 @@ libs: language: c++ headers: - src/compiler/config.h + - src/compiler/config_protobuf.h - src/compiler/cpp_generator.h - src/compiler/cpp_generator_helpers.h - src/compiler/csharp_generator.h diff --git a/src/compiler/BUILD b/src/compiler/BUILD new file mode 100644 index 00000000000..9a38f942939 --- /dev/null +++ b/src/compiler/BUILD @@ -0,0 +1,120 @@ +# gRPC Bazel BUILD file. +# +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) # Apache v2 + +exports_files(["LICENSE"]) + +package( + default_visibility = ["//visibility:public"], + features = [ + "-layering_check", + "-parse_headers", + ], +) + +load( + "//bazel:grpc_build_system.bzl", + "grpc_cc_library", + "grpc_proto_plugin", +) + +grpc_cc_library( + name = "grpc_plugin_support", + srcs = [ + "cpp_generator.cc", + "csharp_generator.cc", + "node_generator.cc", + "objective_c_generator.cc", + "php_generator.cc", + "python_generator.cc", + "ruby_generator.cc", + ], + hdrs = [ + "config_protobuf.h", + "config.h", + "cpp_generator.h", + "cpp_generator_helpers.h", + "cpp_plugin.h", + "csharp_generator.h", + "csharp_generator_helpers.h", + "generator_helpers.h", + "node_generator.h", + "node_generator_helpers.h", + "objective_c_generator.h", + "objective_c_generator_helpers.h", + "php_generator.h", + "php_generator_helpers.h", + "protobuf_plugin.h", + "python_generator.h", + "python_generator_helpers.h", + "python_private_generator.h", + "ruby_generator.h", + "ruby_generator_helpers-inl.h", + "ruby_generator_map-inl.h", + "ruby_generator_string-inl.h", + "schema_interface.h", + ], + external_deps = [ + "protobuf_clib", + ], + language = "c++", + deps = [ + "//:grpc++_config_proto", + ], +) + +grpc_proto_plugin( + name = "grpc_cpp_plugin", + srcs = ["cpp_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_csharp_plugin", + srcs = ["csharp_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_node_plugin", + srcs = ["node_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_objective_c_plugin", + srcs = ["objective_c_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_php_plugin", + srcs = ["php_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_python_plugin", + srcs = ["python_plugin.cc"], + deps = [":grpc_plugin_support"], +) + +grpc_proto_plugin( + name = "grpc_ruby_plugin", + srcs = ["ruby_plugin.cc"], + deps = [":grpc_plugin_support"], +) diff --git a/src/compiler/config.h b/src/compiler/config.h index cfdc3036247..60772f2be68 100644 --- a/src/compiler/config.h +++ b/src/compiler/config.h @@ -19,35 +19,7 @@ #ifndef SRC_COMPILER_CONFIG_H #define SRC_COMPILER_CONFIG_H -#include - -#ifndef GRPC_CUSTOM_CODEGENERATOR -#include -#define GRPC_CUSTOM_CODEGENERATOR ::google::protobuf::compiler::CodeGenerator -#define GRPC_CUSTOM_GENERATORCONTEXT \ - ::google::protobuf::compiler::GeneratorContext -#endif - -#ifndef GRPC_CUSTOM_PRINTER -#include -#include -#include -#define GRPC_CUSTOM_PRINTER ::google::protobuf::io::Printer -#define GRPC_CUSTOM_CODEDOUTPUTSTREAM ::google::protobuf::io::CodedOutputStream -#define GRPC_CUSTOM_STRINGOUTPUTSTREAM \ - ::google::protobuf::io::StringOutputStream -#endif - -#ifndef GRPC_CUSTOM_PLUGINMAIN -#include -#define GRPC_CUSTOM_PLUGINMAIN ::google::protobuf::compiler::PluginMain -#endif - -#ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER -#include -#define GRPC_CUSTOM_PARSEGENERATORPARAMETER \ - ::google::protobuf::compiler::ParseGeneratorParameter -#endif +#include "src/compiler/config_protobuf.h" #ifndef GRPC_CUSTOM_STRING #include diff --git a/src/compiler/config_protobuf.h b/src/compiler/config_protobuf.h new file mode 100644 index 00000000000..06d5073f433 --- /dev/null +++ b/src/compiler/config_protobuf.h @@ -0,0 +1,52 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef SRC_COMPILER_CONFIG_PROTOBUF_H +#define SRC_COMPILER_CONFIG_PROTOBUF_H + +#include + +#ifndef GRPC_CUSTOM_CODEGENERATOR +#include +#define GRPC_CUSTOM_CODEGENERATOR ::google::protobuf::compiler::CodeGenerator +#define GRPC_CUSTOM_GENERATORCONTEXT \ + ::google::protobuf::compiler::GeneratorContext +#endif + +#ifndef GRPC_CUSTOM_PRINTER +#include +#include +#include +#define GRPC_CUSTOM_PRINTER ::google::protobuf::io::Printer +#define GRPC_CUSTOM_CODEDOUTPUTSTREAM ::google::protobuf::io::CodedOutputStream +#define GRPC_CUSTOM_STRINGOUTPUTSTREAM \ + ::google::protobuf::io::StringOutputStream +#endif + +#ifndef GRPC_CUSTOM_PLUGINMAIN +#include +#define GRPC_CUSTOM_PLUGINMAIN ::google::protobuf::compiler::PluginMain +#endif + +#ifndef GRPC_CUSTOM_PARSEGENERATORPARAMETER +#include +#define GRPC_CUSTOM_PARSEGENERATORPARAMETER \ + ::google::protobuf::compiler::ParseGeneratorParameter +#endif + +#endif // SRC_COMPILER_CONFIG_PROTOBUF_H diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0f560fd1063..7a1baae36cd 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7184,6 +7184,7 @@ ], "headers": [ "src/compiler/config.h", + "src/compiler/config_protobuf.h", "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", "src/compiler/csharp_generator.h", @@ -7210,6 +7211,7 @@ "name": "grpc_plugin_support", "src": [ "src/compiler/config.h", + "src/compiler/config_protobuf.h", "src/compiler/cpp_generator.cc", "src/compiler/cpp_generator.h", "src/compiler/cpp_generator_helpers.h", From 5779dd935a22c699a1c33be35b32bee2053a3aba Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 10 Jul 2019 13:52:31 -0700 Subject: [PATCH 614/676] Qualify the error code with StatusCode:: --- src/cpp/client/secure_credentials.cc | 21 ++++++++++++--------- test/cpp/client/credentials_test.cc | 10 +++++----- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 5de5a76194e..ebff8af3e5a 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -139,7 +139,8 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, void operator()(grpc_json* json) { grpc_json_destroy(json); } }; if (options == nullptr) { - return grpc::Status(grpc::INVALID_ARGUMENT, "options cannot be nullptr."); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "options cannot be nullptr."); } ClearStsCredentialsOptions(options); std::vector scratchpad(json_string.c_str(), @@ -147,7 +148,7 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, std::unique_ptr json( grpc_json_parse_string(&scratchpad[0])); if (json == nullptr) { - return grpc::Status(grpc::INVALID_ARGUMENT, "Invalid json."); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Invalid json."); } // Required fields. @@ -155,7 +156,7 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, json.get(), "token_exchange_service_uri", nullptr); if (value == nullptr) { ClearStsCredentialsOptions(options); - return grpc::Status(grpc::INVALID_ARGUMENT, + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "token_exchange_service_uri must be specified."); } options->token_exchange_service_uri.assign(value); @@ -163,7 +164,7 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, grpc_json_get_string_property(json.get(), "subject_token_path", nullptr); if (value == nullptr) { ClearStsCredentialsOptions(options); - return grpc::Status(grpc::INVALID_ARGUMENT, + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "subject_token_path must be specified."); } options->subject_token_path.assign(value); @@ -171,7 +172,7 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, grpc_json_get_string_property(json.get(), "subject_token_type", nullptr); if (value == nullptr) { ClearStsCredentialsOptions(options); - return grpc::Status(grpc::INVALID_ARGUMENT, + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "subject_token_type must be specified."); } options->subject_token_type.assign(value); @@ -199,7 +200,8 @@ grpc::Status StsCredentialsOptionsFromJson(const grpc::string& json_string, // Builds STS credentials Options from the $STS_CREDENTIALS env var. grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options) { if (options == nullptr) { - return grpc::Status(grpc::INVALID_ARGUMENT, "options cannot be nullptr."); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "options cannot be nullptr."); } ClearStsCredentialsOptions(options); grpc_slice json_string = grpc_empty_slice(); @@ -214,13 +216,14 @@ grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options) { }; if (sts_creds_path == nullptr) { - status = grpc::Status(grpc::NOT_FOUND, + status = grpc::Status(grpc::StatusCode::NOT_FOUND, "STS_CREDENTIALS environment variable not set."); return cleanup(); } error = grpc_load_file(sts_creds_path, 1, &json_string); if (error != GRPC_ERROR_NONE) { - status = grpc::Status(grpc::NOT_FOUND, grpc_error_string(error)); + status = + grpc::Status(grpc::StatusCode::NOT_FOUND, grpc_error_string(error)); return cleanup(); } status = StsCredentialsOptionsFromJson( diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index d560fb6d8e8..ba004efe0d9 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -119,7 +119,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsJson) { I'm not a valid JSON. )"; EXPECT_EQ( - grpc::INVALID_ARGUMENT, + grpc::StatusCode::INVALID_ARGUMENT, grpc::experimental::StsCredentialsOptionsFromJson(invalid_json, &options) .error_code()); @@ -130,7 +130,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsJson) { })"; auto status = grpc::experimental::StsCredentialsOptionsFromJson( invalid_json_missing_subject_token_type, &options); - EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code()); EXPECT_THAT(status.error_message(), ::testing::HasSubstr("subject_token_type")); @@ -141,7 +141,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsJson) { })"; status = grpc::experimental::StsCredentialsOptionsFromJson( invalid_json_missing_subject_token_path, &options); - EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code()); EXPECT_THAT(status.error_message(), ::testing::HasSubstr("subject_token_path")); @@ -152,7 +152,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsJson) { })"; status = grpc::experimental::StsCredentialsOptionsFromJson( invalid_json_missing_token_exchange_uri, &options); - EXPECT_EQ(grpc::INVALID_ARGUMENT, status.error_code()); + EXPECT_EQ(grpc::StatusCode::INVALID_ARGUMENT, status.error_code()); EXPECT_THAT(status.error_message(), ::testing::HasSubstr("token_exchange_service_uri")); } @@ -162,7 +162,7 @@ TEST_F(CredentialsTest, StsCredentialsOptionsFromEnv) { gpr_unsetenv("STS_CREDENTIALS"); grpc::experimental::StsCredentialsOptions options; auto status = grpc::experimental::StsCredentialsOptionsFromEnv(&options); - EXPECT_EQ(grpc::NOT_FOUND, status.error_code()); + EXPECT_EQ(grpc::StatusCode::NOT_FOUND, status.error_code()); // Set env and check for success. const char valid_json[] = R"( From 4a9667721934f99c430e2e8f759d38992da635e8 Mon Sep 17 00:00:00 2001 From: Keith Moyer Date: Mon, 17 Jun 2019 17:38:59 -0700 Subject: [PATCH 615/676] Use struct-defined initialization when available The grpc_polling_entity and grpc_httpcli_response types have default member initializer values specified, to indicate what a cleared variable of those types should have as values. This file overrides that, however, by directly performing a memset to 0 over the structures. Instead, the initialization values defined by the type should be honored. Local types that include these types are also upgraded to specify default member initializer values to simplify clearing them. This fixes -Wclass-memaccess warnings in modern versions of GCC. --- test/core/util/port_server_client.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/core/util/port_server_client.cc b/test/core/util/port_server_client.cc index 9a4159944bf..8c48a5467c1 100644 --- a/test/core/util/port_server_client.cc +++ b/test/core/util/port_server_client.cc @@ -35,9 +35,9 @@ #include "src/core/lib/http/httpcli.h" typedef struct freereq { - gpr_mu* mu; - grpc_polling_entity pops; - int done; + gpr_mu* mu = nullptr; + grpc_polling_entity pops = {}; + int done = 0; } freereq; static void destroy_pops_and_shutdown(void* p, grpc_error* error) { @@ -68,9 +68,9 @@ void grpc_free_port_using_server(int port) { grpc_init(); - memset(&pr, 0, sizeof(pr)); + pr = {}; memset(&req, 0, sizeof(req)); - memset(&rsp, 0, sizeof(rsp)); + rsp = {}; grpc_pollset* pollset = static_cast(gpr_zalloc(grpc_pollset_size())); @@ -117,13 +117,13 @@ void grpc_free_port_using_server(int port) { } typedef struct portreq { - gpr_mu* mu; - grpc_polling_entity pops; - int port; - int retries; - char* server; - grpc_httpcli_context* ctx; - grpc_httpcli_response response; + gpr_mu* mu = nullptr; + grpc_polling_entity pops = {}; + int port = 0; + int retries = 0; + char* server = nullptr; + grpc_httpcli_context* ctx = nullptr; + grpc_httpcli_response response = {}; } portreq; static void got_port_from_server(void* arg, grpc_error* error) { @@ -167,7 +167,7 @@ static void got_port_from_server(void* arg, grpc_error* error) { req.host = pr->server; req.http.path = const_cast("/get"); grpc_http_response_destroy(&pr->response); - memset(&pr->response, 0, sizeof(pr->response)); + pr->response = {}; grpc_resource_quota* resource_quota = grpc_resource_quota_create("port_server_client/pick_retry"); grpc_httpcli_get(pr->ctx, &pr->pops, resource_quota, &req, @@ -202,7 +202,7 @@ int grpc_pick_port_using_server(void) { grpc_init(); { grpc_core::ExecCtx exec_ctx; - memset(&pr, 0, sizeof(pr)); + pr = {}; memset(&req, 0, sizeof(req)); grpc_pollset* pollset = static_cast(gpr_zalloc(grpc_pollset_size())); From a2eb267ccb7440212e21cbbd405e712fe9db78ea Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 10 Jul 2019 14:29:55 -0700 Subject: [PATCH 616/676] Clarify std:: usage --- doc/core/moving-to-c++.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/core/moving-to-c++.md b/doc/core/moving-to-c++.md index 4c745b38a90..717e2267b33 100644 --- a/doc/core/moving-to-c++.md +++ b/doc/core/moving-to-c++.md @@ -21,9 +21,13 @@ C++ compatible with ## Constraints -- No use of standard library +- No use of standard library if it requires link-time dependency - Standard library makes wrapping difficult/impossible and also reduces platform portability - This takes precedence over using C++ style guide +- Limited use of standard library if it does not require link-time dependency + - We can use things from `std::` as long as they are header-only implementations. + - Since the standard library API does not specify whether any given part of the API is implemented header-only, the only way to know is to try using something and see if our tests fail. + - Since there is no guarantee that some header-only implementation in the standard library will remain header-only in the future, we should define our own API in lib/gprpp that is an alias for the thing we want to use in `std::` and use the gprpp API in core. That way, if we later need to stop using the thing from `std::`, we can replace the alias with our own implementation. - But lambdas are ok - As are third-party libraries that meet our build requirements (such as many parts of abseil) - There will be some C++ features that don't work From 7e3a9b6b236174000e673771cfbae22a42d05621 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 10 Jul 2019 14:54:44 -0700 Subject: [PATCH 617/676] Remove error arg - reviewer comment --- .../transport/chttp2/transport/chttp2_transport.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index b05a48a6a0c..6254369ef69 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1232,10 +1232,10 @@ static grpc_closure* add_closure_barrier(grpc_closure* closure) { return closure; } -static void null_then_sched_closure(grpc_closure** closure, grpc_error* error) { +static void null_then_sched_closure(grpc_closure** closure) { grpc_closure* c = *closure; *closure = nullptr; - GRPC_CLOSURE_SCHED(c, error); + GRPC_CLOSURE_SCHED(c, GRPC_ERROR_NONE); } void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, @@ -1902,7 +1902,7 @@ void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t, } grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[0], s->recv_initial_metadata); - null_then_sched_closure(&s->recv_initial_metadata_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_initial_metadata_ready); } } @@ -1982,10 +1982,10 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t, s->unprocessed_incoming_frames_buffer_cached_length = s->unprocessed_incoming_frames_buffer.length; if (error == GRPC_ERROR_NONE && *s->recv_message != nullptr) { - null_then_sched_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_message_ready); } else if (s->published_metadata[1] != GRPC_METADATA_NOT_PUBLISHED) { *s->recv_message = nullptr; - null_then_sched_closure(&s->recv_message_ready, GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_message_ready); } GRPC_ERROR_UNREF(error); } @@ -2051,8 +2051,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, s->collecting_stats = nullptr; grpc_chttp2_incoming_metadata_buffer_publish(&s->metadata_buffer[1], s->recv_trailing_metadata); - null_then_sched_closure(&s->recv_trailing_metadata_finished, - GRPC_ERROR_NONE); + null_then_sched_closure(&s->recv_trailing_metadata_finished); } } } From 444806583d7aace199b3aa83051d08315239fa7e Mon Sep 17 00:00:00 2001 From: Qiancheng Zhao Date: Wed, 10 Jul 2019 15:26:53 -0700 Subject: [PATCH 618/676] lazy resolving lb policy creation --- .../filters/client_channel/client_channel.cc | 100 ++++++++++-------- .../resolver/fake/fake_resolver.cc | 1 - .../client_channel/resolving_lb_policy.cc | 59 ++--------- .../client_channel/resolving_lb_policy.h | 15 +-- test/cpp/end2end/grpclb_end2end_test.cc | 4 + 5 files changed, 73 insertions(+), 106 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0b612e67a33..39ca3e5abb2 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -210,6 +210,10 @@ class ChannelData { ChannelData(grpc_channel_element_args* args, grpc_error** error); ~ChannelData(); + void CreateResolvingLoadBalancingPolicyLocked(); + + void DestroyResolvingLoadBalancingPolicyLocked(); + static bool ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, RefCountedPtr* lb_policy_config, @@ -235,8 +239,10 @@ class ChannelData { const size_t per_rpc_retry_buffer_size_; grpc_channel_stack* owning_stack_; ClientChannelFactory* client_channel_factory_; - UniquePtr server_name_; + const grpc_channel_args* channel_args_; RefCountedPtr default_service_config_; + UniquePtr server_name_; + UniquePtr target_uri_; channelz::ChannelNode* channelz_node_; // @@ -1226,59 +1232,61 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, &new_args); - UniquePtr target_uri(proxy_name != nullptr ? proxy_name - : gpr_strdup(server_uri)); + target_uri_.reset(proxy_name != nullptr ? proxy_name + : gpr_strdup(server_uri)); + channel_args_ = new_args != nullptr + ? new_args + : grpc_channel_args_copy(args->channel_args); + if (!ResolverRegistry::IsValidTarget(target_uri_.get())) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("the target uri is not valid."); + return; + } + *error = GRPC_ERROR_NONE; +} + +ChannelData::~ChannelData() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p: destroying channel", this); + } + DestroyResolvingLoadBalancingPolicyLocked(); + grpc_channel_args_destroy(channel_args_); + // Stop backup polling. + grpc_client_channel_stop_backup_polling(interested_parties_); + grpc_pollset_set_destroy(interested_parties_); + GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel"); + GRPC_COMBINER_UNREF(combiner_, "client_channel"); + GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED)); + grpc_connectivity_state_destroy(&state_tracker_); + gpr_mu_destroy(&info_mu_); +} + +void ChannelData::CreateResolvingLoadBalancingPolicyLocked() { // Instantiate resolving LB policy. LoadBalancingPolicy::Args lb_args; lb_args.combiner = combiner_; lb_args.channel_control_helper = UniquePtr( New(this)); - lb_args.args = new_args != nullptr ? new_args : args->channel_args; + lb_args.args = channel_args_; + UniquePtr target_uri(strdup(target_uri_.get())); resolving_lb_policy_.reset(New( std::move(lb_args), &grpc_client_channel_routing_trace, - std::move(target_uri), ProcessResolverResultLocked, this, error)); - grpc_channel_args_destroy(new_args); - if (*error != GRPC_ERROR_NONE) { - // Orphan the resolving LB policy and flush the exec_ctx to ensure - // that it finishes shutting down. This ensures that if we are - // failing, we destroy the ClientChannelControlHelper (and thus - // unref the channel stack) before we return. - // TODO(roth): This is not a complete solution, because it only - // catches the case where channel stack initialization fails in this - // particular filter. If there is a failure in a different filter, we - // will leave a dangling ref here, which can cause a crash. Fortunately, - // in practice, there are no other filters that can cause failures in - // channel stack initialization, so this works for now. - resolving_lb_policy_.reset(); - ExecCtx::Get()->Flush(); - } else { - grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), - interested_parties_); - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this, - resolving_lb_policy_.get()); - } + std::move(target_uri), ProcessResolverResultLocked, this)); + grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(), + interested_parties_); + if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { + gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this, + resolving_lb_policy_.get()); } } -ChannelData::~ChannelData() { - if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { - gpr_log(GPR_INFO, "chand=%p: destroying channel", this); - } +void ChannelData::DestroyResolvingLoadBalancingPolicyLocked() { if (resolving_lb_policy_ != nullptr) { grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(), interested_parties_); resolving_lb_policy_.reset(); } - // Stop backup polling. - grpc_client_channel_stop_backup_polling(interested_parties_); - grpc_pollset_set_destroy(interested_parties_); - GRPC_COMBINER_UNREF(data_plane_combiner_, "client_channel"); - GRPC_COMBINER_UNREF(combiner_, "client_channel"); - GRPC_ERROR_UNREF(disconnect_error_.Load(MemoryOrder::RELAXED)); - grpc_connectivity_state_destroy(&state_tracker_); - gpr_mu_destroy(&info_mu_); } void ChannelData::ProcessLbPolicy( @@ -1500,10 +1508,7 @@ void ChannelData::StartTransportOpLocked(void* arg, grpc_error* ignored) { GPR_ASSERT(chand->disconnect_error_.CompareExchangeStrong( &error, op->disconnect_with_error, MemoryOrder::ACQ_REL, MemoryOrder::ACQUIRE)); - grpc_pollset_set_del_pollset_set( - chand->resolving_lb_policy_->interested_parties(), - chand->interested_parties_); - chand->resolving_lb_policy_.reset(); + chand->DestroyResolvingLoadBalancingPolicyLocked(); // Will delete itself. New( chand, GRPC_CHANNEL_SHUTDOWN, "shutdown from API", @@ -1574,6 +1579,8 @@ void ChannelData::TryToConnectLocked(void* arg, grpc_error* error_ignored) { auto* chand = static_cast(arg); if (chand->resolving_lb_policy_ != nullptr) { chand->resolving_lb_policy_->ExitIdleLocked(); + } else { + chand->CreateResolvingLoadBalancingPolicyLocked(); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack_, "TryToConnect"); } @@ -3463,6 +3470,15 @@ void CallData::StartPickLocked(void* arg, grpc_error* error) { ChannelData* chand = static_cast(elem->channel_data); GPR_ASSERT(calld->connected_subchannel_ == nullptr); GPR_ASSERT(calld->subchannel_call_ == nullptr); + // picker's being null means the channel is currently in IDLE state. The + // incoming call will make the channel exit IDLE and queue itself. + if (chand->picker() == nullptr) { + // We are currently in the data plane. + // Bounce into the control plane to exit IDLE. + chand->CheckConnectivityState(true); + calld->AddCallToQueuedPicksLocked(elem); + return; + } // Apply service config to call if needed. calld->MaybeApplyServiceConfigToCallLocked(elem); // If this is a retry, use the send_initial_metadata payload that diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index c5a27f127b8..761b27292da 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -196,7 +196,6 @@ void FakeResolverResponseGenerator::SetResponse(Resolver::Result result) { grpc_combiner_scheduler(resolver_->combiner())), GRPC_ERROR_NONE); } else { - GPR_ASSERT(!has_result_); has_result_ = true; result_ = std::move(result); } diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 180b0fcbbf4..4b61df09959 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -181,52 +181,29 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper // ResolvingLoadBalancingPolicy // -ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( - Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, - RefCountedPtr child_lb_config, - grpc_error** error) - : LoadBalancingPolicy(std::move(args)), - tracer_(tracer), - target_uri_(std::move(target_uri)), - child_policy_name_(std::move(child_policy_name)), - child_lb_config_(std::move(child_lb_config)) { - GPR_ASSERT(child_policy_name_ != nullptr); - // Don't fetch service config, since this ctor is for use in nested LB - // policies, not at the top level, and we only fetch the service - // config at the top level. - grpc_arg arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(args.args, &arg, 1); - *error = Init(*new_args); - grpc_channel_args_destroy(new_args); -} - ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, grpc_error** error) + void* process_resolver_result_user_data) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), target_uri_(std::move(target_uri)), process_resolver_result_(process_resolver_result), process_resolver_result_user_data_(process_resolver_result_user_data) { GPR_ASSERT(process_resolver_result != nullptr); - *error = Init(*args.args); -} - -grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { resolver_ = ResolverRegistry::CreateResolver( - target_uri_.get(), &args, interested_parties(), combiner(), + target_uri_.get(), args.args, interested_parties(), combiner(), UniquePtr(New(Ref()))); - if (resolver_ == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + // Since the validity of args has been checked when create the channel, + // CreateResolver() must return a non-null result. + GPR_ASSERT(resolver_ != nullptr); + if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { + gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); } - // Return our picker to the channel. channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, UniquePtr(New(Ref()))); - return GRPC_ERROR_NONE; + GRPC_CHANNEL_CONNECTING, + UniquePtr(New(Ref()))); + resolver_->StartLocked(); } ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { @@ -262,10 +239,6 @@ void ResolvingLoadBalancingPolicy::ExitIdleLocked() { if (lb_policy_ != nullptr) { lb_policy_->ExitIdleLocked(); if (pending_lb_policy_ != nullptr) pending_lb_policy_->ExitIdleLocked(); - } else { - if (!started_resolving_ && resolver_ != nullptr) { - StartResolvingLocked(); - } } } @@ -278,18 +251,6 @@ void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { if (pending_lb_policy_ != nullptr) pending_lb_policy_->ResetBackoffLocked(); } -void ResolvingLoadBalancingPolicy::StartResolvingLocked() { - if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { - gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); - } - GPR_ASSERT(!started_resolving_); - started_resolving_ = true; - channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, - UniquePtr(New(Ref()))); - resolver_->StartLocked(); -} - void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { if (resolver_ == nullptr) { GRPC_ERROR_UNREF(error); diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index e91ea832661..d8447c18cf5 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -51,16 +51,6 @@ namespace grpc_core { // child LB policy and config to use. class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { public: - // If error is set when this returns, then construction failed, and - // the caller may not use the new object. - ResolvingLoadBalancingPolicy( - Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, - RefCountedPtr child_lb_config, - grpc_error** error); - - // Private ctor, to be used by client_channel only! - // // Synchronous callback that takes the resolver result and sets // lb_policy_name and lb_policy_config to point to the right data. // Returns true if the service config has changed since the last result. @@ -77,7 +67,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, grpc_error** error); + void* process_resolver_result_user_data); virtual const char* name() const override { return "resolving_lb"; } @@ -98,10 +88,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ~ResolvingLoadBalancingPolicy(); - grpc_error* Init(const grpc_channel_args& args); void ShutdownLocked() override; - void StartResolvingLocked(); void OnResolverError(grpc_error* error); void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, @@ -126,7 +114,6 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Resolver and associated state. OrphanablePtr resolver_; - bool started_resolving_ = false; bool previous_resolution_contained_addresses_ = false; // Child LB policy. diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index e3b79c810cd..d71dafc855f 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -1618,6 +1618,8 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); SetNextResolution(addresses); + // Ask channel to connect to trigger resolver creation. + channel_->GetState(true); // The re-resolution result will contain the addresses of the same balancer // and a new fallback backend. addresses.clear(); @@ -1669,6 +1671,8 @@ class UpdatesWithClientLoadReportingTest : public GrpclbEnd2endTest { }; TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { + // Ask channel to connect to trigger resolver creation. + channel_->GetState(true); std::vector addresses; addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); SetNextResolution(addresses); From 39775cf30fe2b29693652184e01a480a8596a89c Mon Sep 17 00:00:00 2001 From: mgravell Date: Thu, 11 Jul 2019 13:07:50 +0100 Subject: [PATCH 619/676] remove delegate allocation and boxing from cancellation registrations --- src/csharp/Grpc.Core.Tests/CallCancellationTest.cs | 11 +++++++++++ src/csharp/Grpc.Core/Internal/AsyncCall.cs | 10 +++------- src/csharp/Grpc.Core/Internal/AsyncCallBase.cs | 8 ++++++++ src/csharp/Grpc.Core/Internal/ClientResponseStream.cs | 3 +-- src/csharp/Grpc.Core/Internal/ServerRequestStream.cs | 4 +--- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/CallCancellationTest.cs b/src/csharp/Grpc.Core.Tests/CallCancellationTest.cs index e040f52380a..753b8b227b1 100644 --- a/src/csharp/Grpc.Core.Tests/CallCancellationTest.cs +++ b/src/csharp/Grpc.Core.Tests/CallCancellationTest.cs @@ -178,5 +178,16 @@ namespace Grpc.Core.Tests Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode); } } + + [Test] + public void CanDisposeDefaultCancellationRegistration() + { + // prove that we're fine to dispose default CancellationTokenRegistration + // values without boxing them to IDisposable for a null-check + var obj = default(CancellationTokenRegistration); + obj.Dispose(); + + using (obj) {} + } } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index a1c688140d1..ce3508d398e 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -38,7 +38,7 @@ namespace Grpc.Core.Internal bool registeredWithChannel; // Dispose of to de-register cancellation token registration - IDisposable cancellationTokenRegistration; + CancellationTokenRegistration cancellationTokenRegistration; // Completion of a pending unary response if not null. TaskCompletionSource unaryResponseTcs; @@ -409,7 +409,7 @@ namespace Grpc.Core.Internal // deadlock. // See https://github.com/grpc/grpc/issues/14777 // See https://github.com/dotnet/corefx/issues/14903 - cancellationTokenRegistration?.Dispose(); + cancellationTokenRegistration.Dispose(); } protected override bool IsClient @@ -509,11 +509,7 @@ namespace Grpc.Core.Internal // Make sure that once cancellationToken for this call is cancelled, Cancel() will be called. private void RegisterCancellationCallback() { - var token = details.Options.CancellationToken; - if (token.CanBeCanceled) - { - cancellationTokenRegistration = token.Register(() => this.Cancel()); - } + cancellationTokenRegistration = RegisterCancellationCallbackForToken(details.Options.CancellationToken); } /// diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 0b99aaf3e21..ac1f9066516 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -394,5 +394,13 @@ namespace Grpc.Core.Internal { HandleReadFinished(success, receivedMessageReader); } + + internal CancellationTokenRegistration RegisterCancellationCallbackForToken(CancellationToken cancellationToken) + { + if (cancellationToken.CanBeCanceled) return cancellationToken.Register(CancelCallFromToken, this); + return default(CancellationTokenRegistration); + } + + private static readonly Action CancelCallFromToken = state => ((AsyncCallBase)state).Cancel(); } } diff --git a/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs b/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs index ab649ee7662..ff73b26dff4 100644 --- a/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs +++ b/src/csharp/Grpc.Core/Internal/ClientResponseStream.cs @@ -49,8 +49,7 @@ namespace Grpc.Core.Internal public async Task MoveNext(CancellationToken token) { - var cancellationTokenRegistration = token.CanBeCanceled ? token.Register(() => call.Cancel()) : (IDisposable) null; - using (cancellationTokenRegistration) + using (call.RegisterCancellationCallbackForToken(token)) { var result = await call.ReadMessageAsync().ConfigureAwait(false); this.current = result; diff --git a/src/csharp/Grpc.Core/Internal/ServerRequestStream.cs b/src/csharp/Grpc.Core/Internal/ServerRequestStream.cs index 058dddb7ebb..f3655139e47 100644 --- a/src/csharp/Grpc.Core/Internal/ServerRequestStream.cs +++ b/src/csharp/Grpc.Core/Internal/ServerRequestStream.cs @@ -49,9 +49,7 @@ namespace Grpc.Core.Internal public async Task MoveNext(CancellationToken token) { - - var cancellationTokenRegistration = token.CanBeCanceled ? token.Register(() => call.Cancel()) : (IDisposable) null; - using (cancellationTokenRegistration) + using (call.RegisterCancellationCallbackForToken(token)) { var result = await call.ReadMessageAsync().ConfigureAwait(false); this.current = result; From 8e4d14fe91053fb4202db948e62dc11bfad8d6e5 Mon Sep 17 00:00:00 2001 From: Wensheng Tang Date: Sun, 7 Jul 2019 02:47:20 +0800 Subject: [PATCH 620/676] Fix the assertion of grpc_udp_server_add_port grpc_udp_server_add_port() can return port = -1 when going fail. @nanahpang also recommands discarding port = 0 --- test/core/iomgr/udp_server_test.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc index f65783a0174..3c9e7108608 100644 --- a/test/core/iomgr/udp_server_test.cc +++ b/test/core/iomgr/udp_server_test.cc @@ -218,7 +218,7 @@ static void test_no_op_with_port(void) { addr->sin_family = AF_INET; GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, snd_buf_size, &handler_factory, - g_num_listeners)); + g_num_listeners) > 0); grpc_udp_server_destroy(s, nullptr); @@ -250,7 +250,7 @@ static void test_no_op_with_port_and_socket_factory(void) { addr->sin_family = AF_INET; GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, snd_buf_size, &handler_factory, - g_num_listeners)); + g_num_listeners) > 0); GPR_ASSERT(socket_factory->number_of_socket_calls == g_num_listeners); GPR_ASSERT(socket_factory->number_of_bind_calls == g_num_listeners); @@ -278,7 +278,7 @@ static void test_no_op_with_port_and_start(void) { addr->sin_family = AF_INET; GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, snd_buf_size, &handler_factory, - g_num_listeners)); + g_num_listeners) > 0); grpc_udp_server_start(s, nullptr, 0, nullptr); GPR_ASSERT(g_number_of_starts == g_num_listeners); @@ -312,7 +312,7 @@ static void test_receive(int number_of_clients) { addr->ss_family = AF_INET; GPR_ASSERT(grpc_udp_server_add_port(s, &resolved_addr, rcv_buf_size, snd_buf_size, &handler_factory, - g_num_listeners)); + g_num_listeners) > 0); svrfd = grpc_udp_server_get_fd(s, 0); GPR_ASSERT(svrfd >= 0); From e8b9e95fa275361d1203217a97e01bbadcd211ee Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 11 Jul 2019 09:53:13 -0700 Subject: [PATCH 621/676] Use RefCountedPtr instead of raw pointer --- src/core/lib/channel/channelz.h | 2 +- src/core/lib/surface/server.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index f8acb531e8a..d26896262ec 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -64,7 +64,7 @@ intptr_t GetParentUuidFromArgs(const grpc_channel_args& args); typedef InlinedVector ChildRefsList; class SocketNode; -typedef InlinedVector ChildSocketsList; +typedef InlinedVector, 10> ChildSocketsList; namespace testing { class CallCountingHelperPeer; diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 8f6df482aa9..6cd86003f01 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1248,7 +1248,7 @@ void grpc_server_populate_server_sockets( channel_data* c = nullptr; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) { - server_sockets->push_back(c->socket_node.get()); + server_sockets->push_back(c->socket_node); } } gpr_mu_unlock(&s->mu_global); From 54a3b642466faf6f71578c44615d31af861b92ef Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 10 Jul 2019 15:49:37 -0700 Subject: [PATCH 622/676] Pull() eats slice from sbuf wrapped byte buffer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At present, a commonly used byte buffer wraps an underlying slice buffer. This is used by grpc_call; it passes a byte buffer for send stream ops through the filter stack and down to the transport. Pull() is a one-way operation; given a slice-buffer backed byte-buffer, it starts with a cursor at index=0 and increments it per pull. There is no way for a cursor to be rewinded. Originally Pull() would ref the slice and return a copy; the slice remains in the underlying buffer and is eventually cleaned up (unref'd). Thus, assuming a slice buffer of size N and assuming we pulled all N slices then we have a total of 2N ref/unref pairs. Since Pull() is essentially acting as a consume operation here, and since it is a one-way operation, we simply transfer the ref rather than create a new ref. This cuts down atomic ops. from 2N to N. This reduces streaming latency slightly for streaming fullstack microbenchmarks: BM_StreamingPingPong/0/1 [polls/iter:0 ] 8.87µs ± 1% 8.91µs ± 1% +0.45% (p=0.002 n=20+20) BM_StreamingPingPong/0/2 [polls/iter:0 ] 11.7µs ± 1% 11.7µs ± 1% +0.34% (p=0.002 n=19+19) BM_StreamingPingPong/8/1 [polls/iter:0 ] 9.11µs ± 1% 9.14µs ± 1% +0.29% (p=0.016 n=19+20) BM_StreamingPingPong/64/1 [polls/iter:0 ] 9.29µs ± 1% 9.27µs ± 1% -0.23% (p=0.029 n=18+19) BM_StreamingPingPong/512/2 [polls/iter:0 ] 13.0µs ± 1% 12.9µs ± 1% -0.52% (p=0.000 n=20+19) BM_StreamingPingPong/4096/1 [polls/iter:0 ] 11.8µs ± 1% 11.8µs ± 1% -0.41% (p=0.007 n=20+20) BM_StreamingPingPong/4096/2 [polls/iter:0 ] 17.4µs ± 1% 17.2µs ± 1% -0.73% (p=0.000 n=19+19) BM_StreamingPingPongMsgs/1 [polls/iter:0 ] 2.87µs ± 1% 2.84µs ± 1% -1.18% (p=0.000 n=19+18) BM_StreamingPingPongMsgs/8 [polls/iter:0 ] 2.85µs ± 1% 2.84µs ± 0% -0.38% (p=0.022 n=20+17) BM_StreamingPingPongMsgs/64 [polls/iter:0 ] 3.00µs ± 1% 2.95µs ± 1% -1.64% (p=0.000 n=19+19) BM_StreamingPingPongMsgs/512 [polls/iter:0 ] 3.32µs ± 1% 3.23µs ± 1% -2.62% (p=0.000 n=20+20) BM_StreamingPingPongMsgs/4096 [polls/iter:0 ] 5.38µs ± 2% 5.30µs ± 1% -1.42% (p=0.000 n=19+20) BM_StreamingPingPongMsgs/32768 [polls/iter:0 ] 24.1µs ± 1% 24.0µs ± 0% -0.47% (p=0.000 n=19+18) BM_StreamingPingPong/0/0 [polls/iter:0 ] 5.71µs ± 1% 5.69µs ± 1% -0.36% (p=0.010 n=19+19) BM_StreamingPingPong/0/1 [polls/iter:0 ] 8.64µs ± 1% 8.68µs ± 1% +0.38% (p=0.004 n=20+18) BM_StreamingPingPong/1/2 [polls/iter:0 ] 11.9µs ± 1% 11.8µs ± 1% -0.36% (p=0.003 n=20+18) BM_StreamingPingPong/64/1 [polls/iter:0 ] 9.09µs ± 1% 9.06µs ± 1% -0.32% (p=0.046 n=20+20) BM_StreamingPingPong/64/2 [polls/iter:0 ] 12.2µs ± 0% 12.1µs ± 1% -0.35% (p=0.001 n=19+20) BM_StreamingPingPong/512/2 [polls/iter:0 ] 12.8µs ± 1% 12.7µs ± 1% -0.46% (p=0.000 n=19+19) BM_StreamingPingPong/4096/1 [polls/iter:0 ] 11.7µs ± 2% 11.6µs ± 1% -0.58% (p=0.004 n=20+20) BM_StreamingPingPong/4096/2 [polls/iter:0 ] 17.1µs ± 1% 17.0µs ± 1% -0.55% (p=0.010 n=20+20) BM_StreamingPingPong/32768/1 [polls/iter:0 ] 30.5µs ± 1% 30.6µs ± 0% +0.27% (p=0.003 n=20+19) BM_StreamingPingPong/262144/2 [polls/iter:0 ] 363µs ± 1% 362µs ± 1% -0.22% (p=0.049 n=20+20) BM_StreamingPingPongMsgs/134217728 [polls/iter:4 writes/iter:8.5 ] 266ms ± 0% 263ms ± 1% -1.23% (p=0.029 n=4+4) BM_StreamingPingPongMsgs/64 [polls/iter:0 ] 2.95µs ± 1% 2.93µs ± 1% -0.97% (p=0.000 n=19+20) BM_StreamingPingPongMsgs/512 [polls/iter:0 ] 3.27µs ± 1% 3.19µs ± 1% -2.32% (p=0.000 n=20+20) BM_StreamingPingPongMsgs/4096 [polls/iter:0 ] 5.33µs ± 2% 5.26µs ± 1% -1.30% (p=0.000 n=20+20) BM_StreamingPingPongMsgs/32768 [polls/iter:0 ] 24.1µs ± 1% 24.0µs ± 0% -0.35% (p=0.001 n=19+20) BM_StreamingPingPongWithCoalescingApi/0/2/1 [polls/iter:0 ] 10.6µs ± 1% 10.6µs ± 1% +0.45% (p=0.014 n=20+20) BM_StreamingPingPongWithCoalescingApi/1/2/0 [polls/iter:0 ] 11.3µs ± 1% 11.3µs ± 1% -0.39% (p=0.046 n=20+20) BM_StreamingPingPongWithCoalescingApi/1/1/1 [polls/iter:0 ] 7.92µs ± 1% 7.88µs ± 1% -0.46% (p=0.012 n=19+18) BM_StreamingPingPongWithCoalescingApi/1/2/1 [polls/iter:0 ] 11.0µs ± 1% 10.9µs ± 1% -0.48% (p=0.001 n=18+20) BM_StreamingPingPongWithCoalescingApi/8/1/0 [polls/iter:0 ] 8.33µs ± 1% 8.30µs ± 1% -0.29% (p=0.025 n=19+19) BM_StreamingPingPongWithCoalescingApi/8/2/0 [polls/iter:0 ] 11.3µs ± 1% 11.3µs ± 1% -0.34% (p=0.011 n=19+19) BM_StreamingPingPongWithCoalescingApi/64/1/0 [polls/iter:0 ] 8.49µs ± 1% 8.41µs ± 1% -1.01% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/64/2/0 [polls/iter:0 ] 11.6µs ± 1% 11.5µs ± 1% -0.80% (p=0.000 n=19+19) BM_StreamingPingPongWithCoalescingApi/64/1/1 [polls/iter:0 ] 8.06µs ± 1% 8.02µs ± 1% -0.51% (p=0.016 n=20+19) BM_StreamingPingPongWithCoalescingApi/64/2/1 [polls/iter:0 ] 11.2µs ± 1% 11.1µs ± 1% -0.69% (p=0.000 n=19+18) BM_StreamingPingPongWithCoalescingApi/512/1/0 [polls/iter:0 ] 8.83µs ± 1% 8.71µs ± 1% -1.34% (p=0.000 n=20+19) BM_StreamingPingPongWithCoalescingApi/512/2/0 [polls/iter:0 ] 12.2µs ± 1% 12.1µs ± 1% -1.35% (p=0.000 n=19+17) BM_StreamingPingPongWithCoalescingApi/512/1/1 [polls/iter:0 ] 8.40µs ± 1% 8.32µs ± 1% -0.92% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/512/2/1 [polls/iter:0 ] 11.9µs ± 1% 11.7µs ± 1% -1.04% (p=0.000 n=19+20) BM_StreamingPingPongWithCoalescingApi/4096/1/0 [polls/iter:0 ] 11.1µs ± 1% 11.0µs ± 1% -0.53% (p=0.002 n=20+19) BM_StreamingPingPongWithCoalescingApi/4096/2/0 [polls/iter:0 ] 16.6µs ± 1% 16.5µs ± 2% -0.47% (p=0.023 n=20+20) BM_StreamingPingPongWithCoalescingApi/32768/1/1 [polls/iter:0 ] 29.6µs ± 1% 29.7µs ± 1% +0.36% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/2097152/1/0 [polls/iter:0 ] 1.59ms ± 9% 1.48ms ± 1% -7.02% (p=0.001 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/2/0 [polls/iter:0 ] 3.17ms ± 9% 2.95ms ± 0% -6.86% (p=0.015 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/1/1 [polls/iter:0 ] 1.59ms ± 9% 1.48ms ± 0% -7.01% (p=0.000 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/2/1 [polls/iter:0 ] 3.17ms ± 9% 2.95ms ± 0% -6.91% (p=0.004 n=20+16) BM_StreamingPingPongWithCoalescingApi/134217728/2/1 [polls/iter:0 ] 512ms ± 2% 509ms ± 2% -0.74% (p=0.040 n=20+20) BM_StreamingPingPongWithCoalescingApi/0/1/0 [polls/iter:0 ] 8.07µs ± 1% 8.02µs ± 1% -0.62% (p=0.001 n=20+20) BM_StreamingPingPongWithCoalescingApi/0/2/0 [polls/iter:0 ] 10.9µs ± 1% 10.9µs ± 1% +0.30% (p=0.014 n=20+20) BM_StreamingPingPongWithCoalescingApi/1/1/0 [polls/iter:0 ] 8.27µs ± 1% 8.24µs ± 1% -0.40% (p=0.040 n=20+20) BM_StreamingPingPongWithCoalescingApi/1/1/1 [polls/iter:0 ] 7.86µs ± 1% 7.83µs ± 1% -0.36% (p=0.041 n=20+19) BM_StreamingPingPongWithCoalescingApi/1/2/1 [polls/iter:0 ] 11.0µs ± 1% 10.9µs ± 1% -0.50% (p=0.000 n=18+19) BM_StreamingPingPongWithCoalescingApi/8/2/1 [polls/iter:0 ] 10.9µs ± 1% 10.9µs ± 1% +0.28% (p=0.005 n=17+19) BM_StreamingPingPongWithCoalescingApi/64/1/0 [polls/iter:0 ] 8.43µs ± 1% 8.40µs ± 1% -0.40% (p=0.012 n=20+18) BM_StreamingPingPongWithCoalescingApi/64/2/1 [polls/iter:0 ] 11.2µs ± 1% 11.1µs ± 1% -0.42% (p=0.019 n=20+18) BM_StreamingPingPongWithCoalescingApi/512/1/0 [polls/iter:0 ] 8.77µs ± 1% 8.70µs ± 1% -0.91% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/512/2/0 [polls/iter:0 ] 12.2µs ± 1% 12.1µs ± 1% -0.71% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/512/2/1 [polls/iter:0 ] 11.8µs ± 1% 11.7µs ± 1% -0.78% (p=0.000 n=20+20) BM_StreamingPingPongWithCoalescingApi/4096/1/0 [polls/iter:0 ] 11.0µs ± 1% 11.0µs ± 1% -0.42% (p=0.030 n=20+20) BM_StreamingPingPongWithCoalescingApi/32768/1/1 [polls/iter:0 ] 29.4µs ± 1% 29.5µs ± 1% +0.35% (p=0.003 n=20+20) BM_StreamingPingPongWithCoalescingApi/2097152/1/0 [polls/iter:0 ] 1.60ms ± 8% 1.48ms ± 1% -7.63% (p=0.002 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/2/0 [polls/iter:0 ] 3.20ms ± 8% 2.96ms ± 1% -7.49% (p=0.020 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/1/1 [polls/iter:0 ] 1.60ms ± 8% 1.48ms ± 1% -7.68% (p=0.000 n=20+16) BM_StreamingPingPongWithCoalescingApi/2097152/2/1 [polls/iter:0 ] 3.20ms ± 9% 2.95ms ± 1% -7.76% (p=0.001 n=20+16) BM_StreamingPingPongWithCoalescingApi/134217728/1/0 [polls/iter:5.8 writes/iter:9.8 ] 255ms ± 2% 248ms ± 1% -2.59% (p=0.017 n=3+7) BM_StreamingPingPongWithCoalescingApi/134217728/2/1 [polls/iter:9.5 writes/iter:18.5 ] 523ms ± 1% 512ms ± 2% -2.09% (p=0.016 n=5+5) --- src/core/lib/transport/byte_stream.cc | 8 +++----- src/core/lib/transport/byte_stream.h | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/lib/transport/byte_stream.cc b/src/core/lib/transport/byte_stream.cc index 16b85ca0db0..1dd234c3761 100644 --- a/src/core/lib/transport/byte_stream.cc +++ b/src/core/lib/transport/byte_stream.cc @@ -55,17 +55,15 @@ void SliceBufferByteStream::Orphan() { bool SliceBufferByteStream::Next(size_t max_size_hint, grpc_closure* on_complete) { - GPR_ASSERT(cursor_ < backing_buffer_.count); + GPR_DEBUG_ASSERT(backing_buffer_.count > 0); return true; } grpc_error* SliceBufferByteStream::Pull(grpc_slice* slice) { - if (shutdown_error_ != GRPC_ERROR_NONE) { + if (GPR_UNLIKELY(shutdown_error_ != GRPC_ERROR_NONE)) { return GRPC_ERROR_REF(shutdown_error_); } - GPR_ASSERT(cursor_ < backing_buffer_.count); - *slice = grpc_slice_ref_internal(backing_buffer_.slices[cursor_]); - ++cursor_; + *slice = grpc_slice_buffer_take_first(&backing_buffer_); return GRPC_ERROR_NONE; } diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index eff832515da..06503015d2c 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -99,9 +99,8 @@ class SliceBufferByteStream : public ByteStream { void Shutdown(grpc_error* error) override; private: - grpc_slice_buffer backing_buffer_; - size_t cursor_ = 0; grpc_error* shutdown_error_ = GRPC_ERROR_NONE; + grpc_slice_buffer backing_buffer_; }; // From c7793ddddeb2475ea274593dfe0f5436e2046ad6 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 11 Jul 2019 10:16:58 -0700 Subject: [PATCH 623/676] Log transport pointer and goaway last stream id when chttp tracing is enabled --- .../transport/chttp2/transport/chttp2_transport.cc | 12 +++++++++--- .../ext/transport/chttp2/transport/frame_goaway.cc | 2 +- src/core/ext/transport/chttp2/transport/internal.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 48c3d002bbd..1b1ec8d3c3a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1140,6 +1140,7 @@ static void queue_setting_update(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, + uint32_t last_stream_id, const grpc_slice& goaway_text) { // Discard the error from a previous goaway frame (if any) if (t->goaway_error != GRPC_ERROR_NONE) { @@ -1153,6 +1154,9 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), GRPC_ERROR_STR_RAW_BYTES, goaway_text); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_INFO, "transport %p got goaway with last stream id %d", t, + last_stream_id)); /* We want to log this irrespective of whether http tracing is enabled */ gpr_log(GPR_INFO, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error, grpc_error_string(t->goaway_error)); @@ -1191,8 +1195,9 @@ static void maybe_start_some_streams(grpc_chttp2_transport* t) { 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_INFO, "HTTP:%s: Allocating new grpc_chttp2_stream %p to id %d", - t->is_client ? "CLI" : "SVR", s, t->next_stream_id)); + GPR_INFO, + "HTTP:%s: Transport %p allocating new grpc_chttp2_stream %p to id %d", + t->is_client ? "CLI" : "SVR", t, s, t->next_stream_id)); GPR_ASSERT(s->id == 0); s->id = t->next_stream_id; @@ -2825,7 +2830,8 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { static void connectivity_state_set(grpc_chttp2_transport* t, grpc_connectivity_state state, const char* reason) { - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "set connectivity_state=%d", state)); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_INFO, "transport %p set connectivity_state=%d", t, state)); grpc_connectivity_state_set(&t->channel_callback.state_tracker, state, reason); } diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.cc b/src/core/ext/transport/chttp2/transport/frame_goaway.cc index e901a6bdc76..6dad3497ec6 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.cc +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -139,7 +139,7 @@ grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, p->state = GRPC_CHTTP2_GOAWAY_DEBUG; if (is_last) { grpc_chttp2_add_incoming_goaway( - t, p->error_code, + t, p->error_code, p->last_stream_id, grpc_slice_new(p->debug_data, p->debug_length, gpr_free)); p->debug_data = nullptr; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 4ab46f9808b..732bc38a0ac 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -752,6 +752,7 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, + uint32_t last_stream_id, const grpc_slice& goaway_text); void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t); From aa3c2a903d556df2bef204ef579bfa0888751c4b Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Thu, 11 Jul 2019 16:04:44 -0700 Subject: [PATCH 624/676] Reworked hack --- gRPC-Core.podspec | 13 ++++++++++--- templates/gRPC-Core.podspec.template | 16 +++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 340c7b4b66b..f92b78f3fdf 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1387,8 +1387,15 @@ Pod::Spec.new do |s| # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include ;g' - find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include \\ +#else\\ + #include "\\1"\\ +#endif;g' + find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\ + #include \\ +#else\\ + #include \\ +#endif;g' END_OF_COMMAND end diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 89a1e9188ff..a22ce9c33e9 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -211,9 +211,15 @@ end # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? - s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include ;g' - find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include \\ +#else\\ + #include "\\1"\\ +#endif;g' + find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\ + #include \\ +#else\\ + #include \\ +#endif;g' end From 4999420c7d980189ecc11d5e58a9387ef7573400 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 11 Jul 2019 16:11:15 -0700 Subject: [PATCH 625/676] Add a test client for certain grpclb fallback scenarios --- CMakeLists.txt | 63 +++++ Makefile | 58 ++++ build.yaml | 15 ++ src/proto/grpc/testing/messages.proto | 20 ++ test/cpp/interop/BUILD | 16 ++ test/cpp/interop/grpclb_fallback_test.cc | 254 ++++++++++++++++++ .../generated/sources_and_headers.json | 29 ++ tools/run_tests/generated/tests.json | 24 ++ 8 files changed, 479 insertions(+) create mode 100644 test/cpp/interop/grpclb_fallback_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dfa4e8009a..fc67b4512ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -638,6 +638,7 @@ add_dependencies(buildtests_cxx grpc_linux_system_roots_test) add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpclb_api_test) add_dependencies(buildtests_cxx grpclb_end2end_test) +add_dependencies(buildtests_cxx grpclb_fallback_test) add_dependencies(buildtests_cxx h2_ssl_cert_test) add_dependencies(buildtests_cxx h2_ssl_session_reuse_test) add_dependencies(buildtests_cxx health_service_end2end_test) @@ -14465,6 +14466,68 @@ target_link_libraries(grpclb_end2end_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(grpclb_fallback_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h + test/cpp/interop/grpclb_fallback_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/empty.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/messages.proto +) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/test.proto +) + +target_include_directories(grpclb_fallback_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(grpclb_fallback_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 2a1bfad1f35..952b20155fd 100644 --- a/Makefile +++ b/Makefile @@ -1228,6 +1228,7 @@ grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test +grpclb_fallback_test: $(BINDIR)/$(CONFIG)/grpclb_fallback_test h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test h2_ssl_session_reuse_test: $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test @@ -1697,6 +1698,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_end2end_test \ + $(BINDIR)/$(CONFIG)/grpclb_fallback_test \ $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \ $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \ @@ -1862,6 +1864,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ $(BINDIR)/$(CONFIG)/grpclb_end2end_test \ + $(BINDIR)/$(CONFIG)/grpclb_fallback_test \ $(BINDIR)/$(CONFIG)/h2_ssl_cert_test \ $(BINDIR)/$(CONFIG)/h2_ssl_session_reuse_test \ $(BINDIR)/$(CONFIG)/health_service_end2end_test \ @@ -2366,6 +2369,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 ) $(E) "[RUN] Testing grpclb_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing grpclb_fallback_test" + $(Q) $(BINDIR)/$(CONFIG)/grpclb_fallback_test || ( echo test grpclb_fallback_test failed ; exit 1 ) $(E) "[RUN] Testing h2_ssl_cert_test" $(Q) $(BINDIR)/$(CONFIG)/h2_ssl_cert_test || ( echo test h2_ssl_cert_test failed ; exit 1 ) $(E) "[RUN] Testing h2_ssl_session_reuse_test" @@ -17488,6 +17493,59 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc +GRPCLB_FALLBACK_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \ + test/cpp/interop/grpclb_fallback_test.cc \ + +GRPCLB_FALLBACK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_FALLBACK_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpclb_fallback_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.5.0+. + +$(BINDIR)/$(CONFIG)/grpclb_fallback_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpclb_fallback_test: $(PROTOBUF_DEP) $(GRPCLB_FALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_FALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_fallback_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +$(OBJDIR)/$(CONFIG)/test/cpp/interop/grpclb_fallback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_grpclb_fallback_test: $(GRPCLB_FALLBACK_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPCLB_FALLBACK_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/interop/grpclb_fallback_test.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc + + H2_SSL_CERT_TEST_SRC = \ test/core/end2end/h2_ssl_cert_test.cc \ diff --git a/build.yaml b/build.yaml index 5915b9ccd64..f42efbb3b21 100644 --- a/build.yaml +++ b/build.yaml @@ -5041,6 +5041,21 @@ targets: - grpc++ - grpc - gpr +- name: grpclb_fallback_test + build: test + language: c++ + src: + - src/proto/grpc/testing/empty.proto + - src/proto/grpc/testing/messages.proto + - src/proto/grpc/testing/test.proto + - test/cpp/interop/grpclb_fallback_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr + - grpc++_test_config - name: h2_ssl_cert_test gtest: true build: test diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto index 3b966ae1b25..4fed83fb389 100644 --- a/src/proto/grpc/testing/messages.proto +++ b/src/proto/grpc/testing/messages.proto @@ -48,6 +48,21 @@ message EchoStatus { string message = 2; } +// The type of route that a client took to reach a server w.r.t. gRPCLB. +// The server must fill in "fallback" if it detects that the RPC reached +// the server via the "gRPCLB fallback" path, and "backend" if it detects +// that the RPC reached the server via "gRPCLB backend" path (i.e. if it got +// the address of this server from the gRPCLB server BalanceLoad RPC). Exactly +// how this detection is done is context and server dependant. +enum GrpclbRouteType { + // Server didn't detect the route that a client took to reach it. + GRPCLB_ROUTE_TYPE_UNKNOWN = 0; + // Indicates that a client reached a server via gRPCLB fallback. + GRPCLB_ROUTE_TYPE_FALLBACK = 1; + // Indicates that a client reached a server as a gRPCLB-given backend. + GRPCLB_ROUTE_TYPE_BACKEND = 2; +} + // Unary request. message SimpleRequest { // Desired payload type in the response from the server. @@ -80,6 +95,9 @@ message SimpleRequest { // Whether SimpleResponse should include server_id. bool fill_server_id = 9; + + // Whether SimpleResponse should include grpclb_route_type. + bool fill_grpclb_route_type = 10; } // Unary response, as configured by the request. @@ -95,6 +113,8 @@ message SimpleResponse { // Server ID. This must be unique among different server instances, // but the same across all RPC's made to a particular server instance. string server_id = 4; + // gRPCLB Path. + GrpclbRouteType grpclb_route_type = 5; } // Client-streaming request. diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 802302bc8bf..e575ef88c5d 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -38,6 +38,22 @@ grpc_cc_library( ], ) +grpc_cc_binary( + name = "grpclb_fallback_test", + srcs = [ + "grpclb_fallback_test.cc", + ], + language = "C++", + deps = [ + "//src/proto/grpc/testing:empty_proto", + "//src/proto/grpc/testing:messages_proto", + "//src/proto/grpc/testing:test_proto", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + "//:grpc++", + ], +) + grpc_cc_binary( name = "interop_server", srcs = [ diff --git a/test/cpp/interop/grpclb_fallback_test.cc b/test/cpp/interop/grpclb_fallback_test.cc new file mode 100644 index 00000000000..ddfad7e01b1 --- /dev/null +++ b/test/cpp/interop/grpclb_fallback_test.cc @@ -0,0 +1,254 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/socket_mutator.h" +#include "src/proto/grpc/testing/empty.pb.h" +#include "src/proto/grpc/testing/messages.pb.h" +#include "src/proto/grpc/testing/test.grpc.pb.h" +#include "src/proto/grpc/testing/test.pb.h" + +#include "test/cpp/util/test_config.h" +#include "test/cpp/util/test_credentials_provider.h" + +DEFINE_string(custom_credentials_type, "", "User provided credentials type."); +DEFINE_string(server_uri, "localhost:1000", "Server URI target"); +DEFINE_string(unroute_lb_and_backend_addrs_cmd, "exit 1", + "Shell command used to make LB and backend addresses unroutable"); +DEFINE_string(blackhole_lb_and_backend_addrs_cmd, "exit 1", + "Shell command used to make LB and backend addresses blackholed"); +DEFINE_string( + test_case, "", + "Test case to run. Valid options are:\n\n" + "fast_fallback_before_startup : fallback before establishing connection to " + "LB;\n" + "fast_fallback_after_startup : fallback after startup due to LB/backend " + "addresses becoming unroutable;\n" + "slow_fallback_before_startup : fallback before startup due to LB address " + "being blackholed;\n" + "slow_fallback_after_startup : fallback after startup due to LB/backend " + "addresses becoming blackholed;\n"); + +using grpc::testing::GrpclbRouteType; +using grpc::testing::SimpleRequest; +using grpc::testing::SimpleResponse; +using grpc::testing::TestService; + +namespace { + +enum RpcMode { + FailFast, + WaitForReady, +}; + +GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds, + RpcMode rpc_mode) { + gpr_log(GPR_INFO, "DoRPCAndGetPath deadline_seconds:%d rpc_mode:%d", + deadline_seconds, rpc_mode); + SimpleRequest request; + SimpleResponse response; + grpc::ClientContext context; + if (rpc_mode == WaitForReady) { + context.set_wait_for_ready(true); + } + request.set_fill_grpclb_route_type(true); + std::chrono::system_clock::time_point deadline = + std::chrono::system_clock::now() + std::chrono::seconds(deadline_seconds); + context.set_deadline(deadline); + grpc::Status s = stub->UnaryCall(&context, request, &response); + if (!s.ok()) { + gpr_log(GPR_INFO, "DoRPCAndGetPath failed. status-message: %s", + s.error_message().c_str()); + return GrpclbRouteType::GRPCLB_ROUTE_TYPE_UNKNOWN; + } + GPR_ASSERT(response.grpclb_route_type() == + GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND || + response.grpclb_route_type() == + GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK); + gpr_log(GPR_INFO, "DoRPCAndGetPath done. grpclb_route_type:%d", + response.grpclb_route_type()); + return response.grpclb_route_type(); +} + +GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds) { + return DoRPCAndGetPath(stub, deadline_seconds, FailFast); +} + +GrpclbRouteType DoWaitForReadyRPCAndGetPath(TestService::Stub* stub, + int deadline_seconds) { + return DoRPCAndGetPath(stub, deadline_seconds, WaitForReady); +} + +bool TcpUserTimeoutMutateFd(int fd, grpc_socket_mutator* mutator) { + int timeout = 20000; // 20 seconds + gpr_log(GPR_INFO, "Setting socket option TCP_USER_TIMEOUT on fd: %d", fd); + if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, + sizeof(timeout))) { + gpr_log(GPR_ERROR, "Failed to set socket option TCP_USER_TIMEOUT"); + abort(); + } + int newval; + socklen_t len = sizeof(newval); + if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len) || + newval != timeout) { + gpr_log(GPR_ERROR, "Failed to set socket option TCP_USER_TIMEOUT"); + abort(); + } + return true; +} + +int TcpUserTimeoutCompare(grpc_socket_mutator* a, grpc_socket_mutator* b) { + return 0; +} + +void TcpUserTimeoutDestroy(grpc_socket_mutator* mutator) { gpr_free(mutator); } + +const grpc_socket_mutator_vtable kTcpUserTimeoutMutatorVtable = + grpc_socket_mutator_vtable{ + .mutate_fd = TcpUserTimeoutMutateFd, + .compare = TcpUserTimeoutCompare, + .destroy = TcpUserTimeoutDestroy, + }; + +std::unique_ptr CreateFallbackTestStub() { + grpc::ChannelArguments channel_args; + grpc_socket_mutator* tcp_user_timeout_mutator = + static_cast( + gpr_malloc(sizeof(tcp_user_timeout_mutator))); + grpc_socket_mutator_init(tcp_user_timeout_mutator, + &kTcpUserTimeoutMutatorVtable); + channel_args.SetSocketMutator(tcp_user_timeout_mutator); + // Allow LB policy to be configured by service config + channel_args.SetInt(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, 0); + std::shared_ptr channel_creds = + grpc::testing::GetCredentialsProvider()->GetChannelCredentials( + FLAGS_custom_credentials_type, &channel_args); + return TestService::NewStub( + grpc::CreateCustomChannel(FLAGS_server_uri, channel_creds, channel_args)); +} + +void RunCommand(const std::string command) { + gpr_log(GPR_INFO, "RunCommand: |%s|", command.c_str()); + int out = std::system(command.c_str()); + if (WIFEXITED(out)) { + int code = WEXITSTATUS(out); + if (code != 0) { + gpr_log(GPR_ERROR, "RunCommand failed exit code:%d command:|%s|", code, + command.c_str()); + abort(); + } + } else { + gpr_log(GPR_ERROR, "RunCommand failed command:|%s|", command.c_str()); + abort(); + } +} + +void RunFallbackBeforeStartupTest( + const std::string break_lb_and_backend_conns_cmd, + int per_rpc_deadline_seconds) { + std::unique_ptr stub = CreateFallbackTestStub(); + RunCommand(break_lb_and_backend_conns_cmd); + for (size_t i = 0; i < 30; i++) { + GrpclbRouteType grpclb_route_type = + DoRPCAndGetPath(stub.get(), per_rpc_deadline_seconds); + if (grpclb_route_type != GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) { + gpr_log(GPR_ERROR, "Expected grpclb route type: FALLBACK. Got: %d", + grpclb_route_type); + abort(); + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } +} + +void DoFastFallbackBeforeStartup() { + RunFallbackBeforeStartupTest(FLAGS_unroute_lb_and_backend_addrs_cmd, 9); +} + +void DoSlowFallbackBeforeStartup() { + RunFallbackBeforeStartupTest(FLAGS_blackhole_lb_and_backend_addrs_cmd, 20); +} + +void RunFallbackAfterStartupTest( + const std::string break_lb_and_backend_conns_cmd) { + std::unique_ptr stub = CreateFallbackTestStub(); + GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub.get(), 20); + if (grpclb_route_type != GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND) { + gpr_log(GPR_ERROR, "Expected grpclb route type: BACKEND. Got: %d", + grpclb_route_type); + abort(); + } + RunCommand(break_lb_and_backend_conns_cmd); + for (size_t i = 0; i < 40; i++) { + GrpclbRouteType grpclb_route_type = + DoWaitForReadyRPCAndGetPath(stub.get(), 1); + // Backends should be unreachable by now, otherwise the test is broken. + GPR_ASSERT(grpclb_route_type != GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND); + if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) { + gpr_log(GPR_INFO, + "Made one successul RPC to a fallback. Now expect the same for " + "the rest."); + break; + } else { + gpr_log(GPR_ERROR, "Retryable RPC failure on iteration: %" PRIdPTR, i); + } + } + for (size_t i = 0; i < 30; i++) { + GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub.get(), 20); + if (grpclb_route_type != GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) { + gpr_log(GPR_ERROR, "Expected grpclb route type: FALLBACK. Got: %d", + grpclb_route_type); + abort(); + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } +} + +void DoFastFallbackAfterStartup() { + RunFallbackAfterStartupTest(FLAGS_unroute_lb_and_backend_addrs_cmd); +} + +void DoSlowFallbackAfterStartup() { + RunFallbackAfterStartupTest(FLAGS_blackhole_lb_and_backend_addrs_cmd); +} +} // namespace + +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + gpr_log(GPR_INFO, "Testing: %s", FLAGS_test_case.c_str()); + if (FLAGS_test_case == "fast_fallback_before_startup") { + DoFastFallbackBeforeStartup(); + gpr_log(GPR_INFO, "DoFastFallbackBeforeStartup done!"); + } else if (FLAGS_test_case == "slow_fallback_before_startup") { + DoSlowFallbackBeforeStartup(); + gpr_log(GPR_INFO, "DoSlowFallbackBeforeStartup done!"); + } else if (FLAGS_test_case == "fast_fallback_after_startup") { + DoFastFallbackAfterStartup(); + gpr_log(GPR_INFO, "DoFastFallbackAfterStartup done!"); + } else if (FLAGS_test_case == "slow_fallback_after_startup") { + DoSlowFallbackAfterStartup(); + gpr_log(GPR_INFO, "DoSlowFallbackAfterStartup done!"); + } else { + gpr_log(GPR_ERROR, "Invalid test case: %s", FLAGS_test_case.c_str()); + abort(); + } +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7a1baae36cd..0b56c7b32df 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4037,6 +4037,35 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_config", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [ + "src/proto/grpc/testing/empty.grpc.pb.h", + "src/proto/grpc/testing/empty.pb.h", + "src/proto/grpc/testing/empty_mock.grpc.pb.h", + "src/proto/grpc/testing/messages.grpc.pb.h", + "src/proto/grpc/testing/messages.pb.h", + "src/proto/grpc/testing/messages_mock.grpc.pb.h", + "src/proto/grpc/testing/test.grpc.pb.h", + "src/proto/grpc/testing/test.pb.h", + "src/proto/grpc/testing/test_mock.grpc.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "grpclb_fallback_test", + "src": [ + "test/cpp/interop/grpclb_fallback_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 2ac529238d5..fe10187fffb 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4813,6 +4813,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "grpclb_fallback_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 34a688050857ee29e413ec3baf833873d9c36bdf Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Thu, 11 Jul 2019 18:31:51 -0700 Subject: [PATCH 626/676] Fixing formatting issues --- gRPC-Core.podspec | 12 ++---------- templates/gRPC-Core.podspec.template | 15 ++++----------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f92b78f3fdf..2dfcb311b5d 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1387,15 +1387,7 @@ Pod::Spec.new do |s| # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\ - #include \\ -#else\\ - #include "\\1"\\ -#endif;g' - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\ - #include \\ -#else\\ - #include \\ -#endif;g' + find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' + find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\\n #include \\\n#else\\\n #include \\\n#endif;g' END_OF_COMMAND end diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index a22ce9c33e9..652c4ed43f0 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -211,15 +211,8 @@ end # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? - s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\ - #include \\ -#else\\ - #include "\\1"\\ -#endif;g' - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\ - #include \\ -#else\\ - #include \\ -#endif;g' + s.prepare_command = <<-END_OF_COMMAND + find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' + find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\\n #include \\\n#else\\\n #include \\\n#endif;g' + END_OF_COMMAND end From 3958a53bf7ba8a847154f55bf1eb50ca503fb220 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 11 Jul 2019 19:08:27 -0700 Subject: [PATCH 627/676] Address review comments; fix sanity --- CMakeLists.txt | 4 ++++ build.yaml | 2 ++ test/cpp/interop/grpclb_fallback_test.cc | 26 ++++++++++++++++++++---- tools/run_tests/generated/tests.json | 10 ++------- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc67b4512ea..a68f5caff81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -638,7 +638,9 @@ add_dependencies(buildtests_cxx grpc_linux_system_roots_test) add_dependencies(buildtests_cxx grpc_tool_test) add_dependencies(buildtests_cxx grpclb_api_test) add_dependencies(buildtests_cxx grpclb_end2end_test) +if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_cxx grpclb_fallback_test) +endif() add_dependencies(buildtests_cxx h2_ssl_cert_test) add_dependencies(buildtests_cxx h2_ssl_session_reuse_test) add_dependencies(buildtests_cxx health_service_end2end_test) @@ -14468,6 +14470,7 @@ target_link_libraries(grpclb_end2end_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX) add_executable(grpclb_fallback_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc @@ -14528,6 +14531,7 @@ target_link_libraries(grpclb_fallback_test ) +endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/build.yaml b/build.yaml index f42efbb3b21..c36b3c72594 100644 --- a/build.yaml +++ b/build.yaml @@ -5056,6 +5056,8 @@ targets: - grpc - gpr - grpc++_test_config + platforms: + - linux - name: h2_ssl_cert_test gtest: true build: test diff --git a/test/cpp/interop/grpclb_fallback_test.cc b/test/cpp/interop/grpclb_fallback_test.cc index ddfad7e01b1..3622482b67d 100644 --- a/test/cpp/interop/grpclb_fallback_test.cc +++ b/test/cpp/interop/grpclb_fallback_test.cc @@ -1,3 +1,21 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #include #include @@ -111,7 +129,7 @@ bool TcpUserTimeoutMutateFd(int fd, grpc_socket_mutator* mutator) { socklen_t len = sizeof(newval); if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len) || newval != timeout) { - gpr_log(GPR_ERROR, "Failed to set socket option TCP_USER_TIMEOUT"); + gpr_log(GPR_ERROR, "Failed to get expected socket option TCP_USER_TIMEOUT"); abort(); } return true; @@ -147,7 +165,7 @@ std::unique_ptr CreateFallbackTestStub() { grpc::CreateCustomChannel(FLAGS_server_uri, channel_creds, channel_args)); } -void RunCommand(const std::string command) { +void RunCommand(const std::string& command) { gpr_log(GPR_INFO, "RunCommand: |%s|", command.c_str()); int out = std::system(command.c_str()); if (WIFEXITED(out)) { @@ -164,7 +182,7 @@ void RunCommand(const std::string command) { } void RunFallbackBeforeStartupTest( - const std::string break_lb_and_backend_conns_cmd, + const std::string& break_lb_and_backend_conns_cmd, int per_rpc_deadline_seconds) { std::unique_ptr stub = CreateFallbackTestStub(); RunCommand(break_lb_and_backend_conns_cmd); @@ -189,7 +207,7 @@ void DoSlowFallbackBeforeStartup() { } void RunFallbackAfterStartupTest( - const std::string break_lb_and_backend_conns_cmd) { + const std::string& break_lb_and_backend_conns_cmd) { std::unique_ptr stub = CreateFallbackTestStub(); GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub.get(), 20); if (grpclb_route_type != GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND) { diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index fe10187fffb..f4757e5ef62 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4817,10 +4817,7 @@ "args": [], "benchmark": false, "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" + "linux" ], "cpu_cost": 1.0, "exclude_configs": [], @@ -4830,10 +4827,7 @@ "language": "c++", "name": "grpclb_fallback_test", "platforms": [ - "linux", - "mac", - "posix", - "windows" + "linux" ], "uses_polling": true }, From a0d9ec81a5503c5d71f317b66682748c5eb34852 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 12 Jul 2019 14:11:26 -0700 Subject: [PATCH 628/676] Add a sanity check for the Python release process. This fixes https://github.com/grpc/grpc/issues/19632. --- tools/release/verify_python_release.py | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 tools/release/verify_python_release.py diff --git a/tools/release/verify_python_release.py b/tools/release/verify_python_release.py new file mode 100644 index 00000000000..af2892b61a5 --- /dev/null +++ b/tools/release/verify_python_release.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +#Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Verifies that all gRPC Python artifacts have been successfully published. + +This script is intended to be run from a directory containing the artifacts +that have been uploaded and only the artifacts that have been uploaded. We use +PyPI's JSON API to verify that the proper filenames and checksums are present. + +Note that PyPI may take several minutes to update its metadata. Don't have a +heart attack immediately. + +This sanity check is a good first step, but ideally, we would automate the +entire release process. +""" + +import argparse +import collections +import hashlib +import os +import requests +import sys + +_DEFAULT_PACKAGES = [ + "grpcio", + "grpcio-tools", + "grpcio-status", + "grpcio-health-checking", + "grpcio-reflection", + "grpcio-channelz", + "grpcio-testing", +] + +Artifact = collections.namedtuple("Artifact", ("filename", "checksum")) + + +def _get_md5_checksum(filename): + """Calculate the md5sum for a file.""" + hash_md5 = hashlib.md5() + with open(filename, 'rb') as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_md5.update(chunk) + return hash_md5.hexdigest() + + +def _get_local_artifacts(): + """Get a set of artifacts representing all files in the cwd.""" + return set( + Artifact(f, _get_md5_checksum(f)) for f in os.listdir(os.getcwd())) + + +def _get_remote_artifacts_for_package(package, version): + """Get a list of artifacts based on PyPi's json metadata. + + Note that this data will not updated immediately after upload. In my + experience, it has taken a minute on average to be fresh. + """ + artifacts = set() + payload = requests.get("https://pypi.org/pypi/{}/{}/json".format( + package, version)).json() + for download_info in payload['releases'][version]: + artifacts.add( + Artifact(download_info['filename'], download_info['md5_digest'])) + return artifacts + + +def _get_remote_artifacts_for_packages(packages, version): + artifacts = set() + for package in packages: + artifacts |= _get_remote_artifacts_for_package(package, version) + return artifacts + + +def _verify_release(version, packages): + """Compare the local artifacts to the packages uploaded to PyPI.""" + local_artifacts = _get_local_artifacts() + remote_artifacts = _get_remote_artifacts_for_packages(packages, version) + if local_artifacts != remote_artifacts: + local_but_not_remote = local_artifacts - remote_artifacts + remote_but_not_local = remote_artifacts - local_artifacts + if local_but_not_remote: + print("The following artifacts exist locally but not remotely.") + for artifact in local_but_not_remote: + print(artifact) + if remote_but_not_local: + print("The following artifacts exist remotely but not locally.") + for artifact in remote_but_not_local: + print(artifact) + sys.exit(1) + print("Release verified successfully.") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + "Verify a release. Run this from a directory containing only the" + "artifacts to be uploaded. Note that PyPI may take several minutes" + "after the upload to reflect the proper metadata." + ) + parser.add_argument("version") + parser.add_argument( + "packages", nargs='*', type=str, default=_DEFAULT_PACKAGES) + args = parser.parse_args() + _verify_release(args.version, args.packages) From 994985be97e59e6379655988a1af56b977749d58 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 12 Jul 2019 10:27:47 -0700 Subject: [PATCH 629/676] Log refcount traces if tracer enabled, even if DEBUG_LOCATION is not used. --- src/core/lib/gprpp/debug_location.h | 5 +- src/core/lib/gprpp/ref_counted.h | 84 +++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/core/lib/gprpp/debug_location.h b/src/core/lib/gprpp/debug_location.h index 287761beafb..d2384fde289 100644 --- a/src/core/lib/gprpp/debug_location.h +++ b/src/core/lib/gprpp/debug_location.h @@ -25,10 +25,12 @@ namespace grpc_core { // No-op for non-debug builds. // Callers can use the DEBUG_LOCATION macro in either case. #ifndef NDEBUG +// TODO(roth): See if there's a way to automatically populate this, +// similarly to how absl::SourceLocation::current() works, so that +// callers don't need to explicitly pass DEBUG_LOCATION anywhere. class DebugLocation { public: DebugLocation(const char* file, int line) : file_(file), line_(line) {} - bool Log() const { return true; } const char* file() const { return file_; } int line() const { return line_; } @@ -40,7 +42,6 @@ class DebugLocation { #else class DebugLocation { public: - bool Log() const { return false; } const char* file() const { return nullptr; } int line() const { return -1; } }; diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index cab1aaaaab1..5c7a5cf0735 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -89,72 +89,114 @@ class RefCount { } // Increases the ref-count by `n`. - void Ref(Value n = 1) { value_.FetchAdd(n, MemoryOrder::RELAXED); } + void Ref(Value n = 1) { +#ifndef NDEBUG + const Value prior = value_.FetchAdd(n, MemoryOrder::RELAXED); + if (trace_flag_ != nullptr && trace_flag_->enabled()) { + gpr_log(GPR_INFO, "%s:%p ref %" PRIdPTR " -> %" PRIdPTR, + trace_flag_->name(), this, prior, prior + n); + } +#else + value_.FetchAdd(n, MemoryOrder::RELAXED); +#endif + } void Ref(const DebugLocation& location, const char* reason, Value n = 1) { #ifndef NDEBUG - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = get(); + const Value prior = value_.FetchAdd(n, MemoryOrder::RELAXED); + if (trace_flag_ != nullptr && trace_flag_->enabled()) { gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + n, reason); + prior, prior + n, reason); } +#else + value_.FetchAdd(n, MemoryOrder::RELAXED); #endif - Ref(n); } // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED); + if (trace_flag_ != nullptr && trace_flag_->enabled()) { + gpr_log(GPR_INFO, "%s:%p ref %" PRIdPTR " -> %" PRIdPTR, + trace_flag_->name(), this, prior, prior + 1); + } assert(prior > 0); #else - Ref(); + value_.FetchAdd(1, MemoryOrder::RELAXED); #endif } void RefNonZero(const DebugLocation& location, const char* reason) { #ifndef NDEBUG - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = get(); + const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED); + if (trace_flag_ != nullptr && trace_flag_->enabled()) { gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s", trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + 1, reason); + prior, prior + 1, reason); } -#endif + assert(prior > 0); +#else RefNonZero(); +#endif } - bool RefIfNonZero() { return value_.IncrementIfNonzero(); } - + bool RefIfNonZero() { +#ifndef NDEBUG + if (trace_flag_ != nullptr && trace_flag_->enabled()) { + const Value prior = get(); + gpr_log(GPR_INFO, "%s:%p ref_if_non_zero %" PRIdPTR " -> %" PRIdPTR, + trace_flag_->name(), this, prior, prior + 1); + } +#endif + return value_.IncrementIfNonzero(); + } bool RefIfNonZero(const DebugLocation& location, const char* reason) { #ifndef NDEBUG - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = get(); + if (trace_flag_ != nullptr && trace_flag_->enabled()) { + const Value prior = get(); gpr_log(GPR_INFO, "%s:%p %s:%d ref_if_non_zero " "%" PRIdPTR " -> %" PRIdPTR " %s", trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs + 1, reason); + prior, prior + 1, reason); } #endif - return RefIfNonZero(); + return value_.IncrementIfNonzero(); } // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { +#ifndef NDEBUG + // Grab a copy of the trace flag before the atomic change, since we + // can't safely access it afterwards if we're going to be freed. + auto* trace_flag = trace_flag_; +#endif const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL); +#ifndef NDEBUG + if (trace_flag != nullptr && trace_flag->enabled()) { + gpr_log(GPR_INFO, "%s:%p unref %" PRIdPTR " -> %" PRIdPTR, + trace_flag->name(), this, prior, prior - 1); + } GPR_DEBUG_ASSERT(prior > 0); +#endif return prior == 1; } bool Unref(const DebugLocation& location, const char* reason) { #ifndef NDEBUG - if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { - const RefCount::Value old_refs = get(); + // Grab a copy of the trace flag before the atomic change, since we + // can't safely access it afterwards if we're going to be freed. + auto* trace_flag = trace_flag_; +#endif + const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL); +#ifndef NDEBUG + if (trace_flag != nullptr && trace_flag->enabled()) { gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s", - trace_flag_->name(), this, location.file(), location.line(), - old_refs, old_refs - 1, reason); + trace_flag->name(), this, location.file(), location.line(), prior, + prior - 1, reason); } + GPR_DEBUG_ASSERT(prior > 0); #endif - return Unref(); + return prior == 1; } private: From c15d246f6a241ffff1ad59abf4d76867949d1706 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 12 Jul 2019 14:56:07 -0700 Subject: [PATCH 630/676] Add constructor test case --- src/core/lib/iomgr/executor/mpmcqueue.h | 4 +- src/core/lib/iomgr/executor/threadpool.h | 2 - test/core/iomgr/threadpool_test.cc | 63 ++++++++++++++---------- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/core/lib/iomgr/executor/mpmcqueue.h b/src/core/lib/iomgr/executor/mpmcqueue.h index 5c62221e9d4..c6102b3add0 100644 --- a/src/core/lib/iomgr/executor/mpmcqueue.h +++ b/src/core/lib/iomgr/executor/mpmcqueue.h @@ -66,8 +66,8 @@ class InfLenFIFOQueue : public MPMCQueueInterface { // Removes the oldest element from the queue and returns it. // This routine will cause the thread to block if queue is currently empty. - // Argument wait_time should be passed in when trace flag turning on (for - // collecting stats info purpose.) + // Argument wait_time should be passed in when turning on the trace flag + // grpc_thread_pool_trace (for collecting stats info purpose.) void* Get(gpr_timespec* wait_time = nullptr); // Returns number of elements in queue currently. diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index d68cbbf7328..3f79bbe9d08 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -79,8 +79,6 @@ class ThreadPoolWorker { void Start() { thd_.Start(); } void Join() { thd_.Join(); } - // GRPC_ABSTRACT_BASE_CLASS - private: // struct for tracking stats of thread struct Stats { diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index e0a9d73f48b..4b36c3dc185 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -20,16 +20,16 @@ #include "test/core/util/test_config.h" -#define SMALL_THREAD_POOL_SIZE 20 -#define LARGE_THREAD_POOL_SIZE 100 -#define THREAD_SMALL_ITERATION 100 -#define THREAD_LARGE_ITERATION 10000 +const int kSmallThreadPoolSize = 20; +const int kLargeThreadPoolSize = 100; +const int kThreadSmallIter = 100; +const int kThreadLargeIter = 10000; // Simple functor for testing. It will count how many times being called. class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { public: friend class SimpleFunctorCheckForAdd; - SimpleFunctorForAdd() : count_(0) { + SimpleFunctorForAdd() { functor_run = &SimpleFunctorForAdd::Run; internal_next = this; internal_success = 0; @@ -51,32 +51,32 @@ class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { class SimpleFunctorCheckForAdd : public grpc_experimental_completion_queue_functor { public: - SimpleFunctorCheckForAdd( - struct grpc_experimental_completion_queue_functor* cb, int ok) { + SimpleFunctorCheckForAdd(int ok, int* count) : count_(count) { functor_run = &SimpleFunctorCheckForAdd::Run; - internal_next = cb; internal_success = ok; } ~SimpleFunctorCheckForAdd() {} static void Run(struct grpc_experimental_completion_queue_functor* cb, int ok) { auto* callback = static_cast(cb); - auto* cb_check = static_cast(callback->internal_next); - GPR_ASSERT(cb_check->count_.Load(grpc_core::MemoryOrder::RELAXED) == ok); + (*callback->count_)++; + GPR_ASSERT(*callback->count_ == callback->internal_success); } + private: + int* count_; }; static void test_add(void) { gpr_log(GPR_INFO, "test_add"); grpc_core::ThreadPool* pool = - grpc_core::New(SMALL_THREAD_POOL_SIZE, "test_add"); + grpc_core::New(kSmallThreadPoolSize, "test_add"); SimpleFunctorForAdd* functor = grpc_core::New(); - for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + for (int i = 0; i < kThreadSmallIter; ++i) { pool->Add(functor); } grpc_core::Delete(pool); - GPR_ASSERT(functor->count() == THREAD_SMALL_ITERATION); + GPR_ASSERT(functor->count() == kThreadSmallIter); grpc_core::Delete(functor); gpr_log(GPR_DEBUG, "Done."); } @@ -108,18 +108,32 @@ class WorkThread { grpc_core::Thread thd_; }; +static void test_constructor(void) { + // Size is 0 case + grpc_core::ThreadPool* pool_size_zero = + grpc_core::New(0); + GPR_ASSERT(pool_size_zero->pool_capacity() == 0); + Delete(pool_size_zero); + // Tests options + grpc_core::Thread::Options options; + options.set_stack_size(192 * 1024); // Random non-default value + grpc_core::ThreadPool* pool = + grpc_core::New(0, "test_constructor", options); + GPR_ASSERT(pool->thread_options().stack_size() == options.stack_size()); + Delete(pool); +} + static void test_multi_add(void) { gpr_log(GPR_INFO, "test_multi_add"); const int num_work_thds = 10; grpc_core::ThreadPool* pool = grpc_core::New( - LARGE_THREAD_POOL_SIZE, "test_multi_add"); + kLargeThreadPoolSize, "test_multi_add"); SimpleFunctorForAdd* functor = grpc_core::New(); WorkThread** work_thds = static_cast( gpr_zalloc(sizeof(WorkThread*) * num_work_thds)); gpr_log(GPR_DEBUG, "Fork threads for adding..."); for (int i = 0; i < num_work_thds; ++i) { - work_thds[i] = - grpc_core::New(pool, functor, THREAD_LARGE_ITERATION); + work_thds[i] = grpc_core::New(pool, functor, kThreadLargeIter); work_thds[i]->Start(); } // Wait for all threads finish @@ -133,29 +147,27 @@ static void test_multi_add(void) { gpr_log(GPR_DEBUG, "Waiting for all closures finish..."); // Destructor of thread pool will wait for all closures to finish grpc_core::Delete(pool); - GPR_ASSERT(functor->count() == THREAD_LARGE_ITERATION * num_work_thds); + GPR_ASSERT(functor->count() == kThreadLargeIter * num_work_thds); grpc_core::Delete(functor); gpr_log(GPR_DEBUG, "Done."); } static void test_one_thread_FIFO(void) { gpr_log(GPR_INFO, "test_one_thread_FIFO"); + int counter = 0; grpc_core::ThreadPool* pool = grpc_core::New(1, "test_one_thread_FIFO"); - SimpleFunctorForAdd* functor = grpc_core::New(); SimpleFunctorCheckForAdd** check_functors = - static_cast(gpr_zalloc( - sizeof(SimpleFunctorCheckForAdd*) * THREAD_SMALL_ITERATION)); - for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { - pool->Add(functor); + static_cast( + gpr_zalloc(sizeof(SimpleFunctorCheckForAdd*) * kThreadSmallIter)); + for (int i = 0; i < kThreadSmallIter; ++i) { check_functors[i] = - grpc_core::New(functor, i + 1); + grpc_core::New(i + 1, &counter); pool->Add(check_functors[i]); } // Destructor of pool will wait until all closures finished. grpc_core::Delete(pool); - grpc_core::Delete(functor); - for (int i = 0; i < THREAD_SMALL_ITERATION; ++i) { + for (int i = 0; i < kThreadSmallIter; ++i) { grpc_core::Delete(check_functors[i]); } gpr_free(check_functors); @@ -165,6 +177,7 @@ static void test_one_thread_FIFO(void) { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); + test_constructor(); test_add(); test_multi_add(); test_one_thread_FIFO(); From ba761f77c55cd2046844f11259fc32bd42355248 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 12 Jul 2019 15:21:11 -0700 Subject: [PATCH 631/676] Yapf. Pylint. Long-form birth certificate. --- tools/release/verify_python_release.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/release/verify_python_release.py b/tools/release/verify_python_release.py index af2892b61a5..6cbc39982a9 100644 --- a/tools/release/verify_python_release.py +++ b/tools/release/verify_python_release.py @@ -13,7 +13,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - """Verifies that all gRPC Python artifacts have been successfully published. This script is intended to be run from a directory containing the artifacts @@ -107,8 +106,7 @@ if __name__ == "__main__": parser = argparse.ArgumentParser( "Verify a release. Run this from a directory containing only the" "artifacts to be uploaded. Note that PyPI may take several minutes" - "after the upload to reflect the proper metadata." - ) + "after the upload to reflect the proper metadata.") parser.add_argument("version") parser.add_argument( "packages", nargs='*', type=str, default=_DEFAULT_PACKAGES) From a381dea062ab3fb62d0d0763ffc75dff30abad72 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 12 Jul 2019 17:08:16 -0700 Subject: [PATCH 632/676] reformat --- test/core/iomgr/threadpool_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index 4b36c3dc185..9c678fa4304 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -62,6 +62,7 @@ class SimpleFunctorCheckForAdd (*callback->count_)++; GPR_ASSERT(*callback->count_ == callback->internal_success); } + private: int* count_; }; From fa4e0f040faa48ec31b97f4778d71f94b73427f8 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 12 Jul 2019 17:45:04 -0700 Subject: [PATCH 633/676] Fix segv in pick_first --- .../filters/client_channel/lb_policy/pick_first/pick_first.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index e0deed27442..411d528354a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -176,7 +176,7 @@ void PickFirst::ExitIdleLocked() { } void PickFirst::ResetBackoffLocked() { - subchannel_list_->ResetBackoffLocked(); + if (subchannel_list_ != nullptr) subchannel_list_->ResetBackoffLocked(); if (latest_pending_subchannel_list_ != nullptr) { latest_pending_subchannel_list_->ResetBackoffLocked(); } From c556a02024a0922a51edb4976343dd6814515f5d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 15 Jul 2019 11:20:17 -0400 Subject: [PATCH 634/676] add per-rpc interop tests to managed grpc-dotnet client --- tools/run_tests/run_interop_tests.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e71d308dcbe..d35723c917e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -208,7 +208,10 @@ class AspNetCoreLanguage: def unimplemented_test_cases(self): return _SKIP_COMPRESSION + \ - _AUTH_TEST_CASES + ['compute_engine_creds'] + \ + ['jwt_token_creds'] + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -821,8 +824,8 @@ def auth_options(language, test_case, google_default_creds_use_key_file, if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: if language in [ - 'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', - 'ruby', 'nodepurejs' + 'csharp', 'csharpcoreclr', 'aspnetcore', 'node', 'php', 'php7', + 'python', 'ruby', 'nodepurejs' ]: env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file else: From 225a878e9f358de573c4e05f119bf106476ed19c Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 11 Jul 2019 18:51:17 -0700 Subject: [PATCH 635/676] Track channelz server sockets in the server node --- src/core/lib/channel/channelz.cc | 33 +++++++++++++++++++++----------- src/core/lib/channel/channelz.h | 11 ++++++++--- src/core/lib/surface/server.cc | 32 +++++++++++++++---------------- src/core/lib/surface/server.h | 8 ++------ 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 184ba17889d..b9f65870cfe 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -309,31 +309,42 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} +void ServerNode::AddChildSocket(RefCountedPtr node) { + MutexLock lock(&child_mu_); + child_sockets_.insert(MakePair(node->uuid(), std::move(node))); +} + +void ServerNode::RemoveChildSocket(intptr_t child_uuid) { + MutexLock lock(&child_mu_); + child_sockets_.erase(child_uuid); +} + char* ServerNode::RenderServerSockets(intptr_t start_socket_id, intptr_t max_results) { - // if user does not set max_results, we choose 500. + // If user does not set max_results, we choose 500. size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - ChildSocketsList socket_refs; - grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); - // declared early so it can be used outside of the loop. - size_t i = 0; - if (!socket_refs.empty()) { - // create list of socket refs + MutexLock lock(&child_mu_); + size_t sockets_rendered = 0; + if (!child_sockets_.empty()) { + // Create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { + const size_t limit = GPR_MIN(child_sockets_.size(), pagination_limit); + for (auto it = child_sockets_.lower_bound(start_socket_id); + it != child_sockets_.end() && sockets_rendered < limit; + ++it, ++sockets_rendered) { grpc_json* socket_ref_json = grpc_json_create_child( nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); json_iterator = grpc_json_add_number_string_child( - socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); + socket_ref_json, nullptr, "socketId", it->first); grpc_json_create_child(json_iterator, socket_ref_json, "name", - socket_refs[i]->remote(), GRPC_JSON_STRING, false); + it->second->remote(), GRPC_JSON_STRING, false); } } - if (i == socket_refs.size()) { + if (sockets_rendered == child_sockets_.size()) { json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, GRPC_JSON_TRUE, false); } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index d26896262ec..a02cb82cc75 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -64,7 +64,6 @@ intptr_t GetParentUuidFromArgs(const grpc_channel_args& args); typedef InlinedVector ChildRefsList; class SocketNode; -typedef InlinedVector, 10> ChildSocketsList; namespace testing { class CallCountingHelperPeer; @@ -207,12 +206,16 @@ class ChannelNode : public BaseNode { class ServerNode : public BaseNode { public: ServerNode(grpc_server* server, size_t channel_tracer_max_nodes); + ~ServerNode() override; grpc_json* RenderJson() override; - char* RenderServerSockets(intptr_t start_socket_id, - intptr_t pagination_limit); + char* RenderServerSockets(intptr_t start_socket_id, intptr_t max_results); + + void AddChildSocket(RefCountedPtr); + + void RemoveChildSocket(intptr_t child_uuid); // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { @@ -232,6 +235,8 @@ class ServerNode : public BaseNode { grpc_server* server_; CallCountingHelper call_counter_; ChannelTrace trace_; + Mutex child_mu_; // Guards child map below. + Map> child_sockets_; }; // Handles channelz bookkeeping for sockets diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 6cd86003f01..a1c7d132ade 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -31,6 +31,7 @@ #include #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/debug/stats.h" #include "src/core/lib/gpr/mpscq.h" @@ -111,7 +112,7 @@ struct channel_data { uint32_t registered_method_max_probes; grpc_closure finish_destroy_channel_closure; grpc_closure channel_connectivity_changed; - grpc_core::RefCountedPtr socket_node; + intptr_t channelz_socket_uuid; }; typedef struct shutdown_tag { @@ -941,7 +942,6 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, static void destroy_channel_elem(grpc_channel_element* elem) { size_t i; channel_data* chand = static_cast(elem->channel_data); - chand->socket_node.reset(); if (chand->registered_methods) { for (i = 0; i < chand->registered_method_slots; i++) { grpc_slice_unref_internal(chand->registered_methods[i].method); @@ -952,6 +952,11 @@ static void destroy_channel_elem(grpc_channel_element* elem) { gpr_free(chand->registered_methods); } if (chand->server) { + if (chand->server->channelz_server != nullptr && + chand->channelz_socket_uuid != 0) { + chand->server->channelz_server->RemoveChildSocket( + chand->channelz_socket_uuid); + } gpr_mu_lock(&chand->server->mu_global); chand->next->prev = chand->prev; chand->prev->next = chand->next; @@ -1144,7 +1149,8 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, void grpc_server_setup_transport( grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - grpc_core::RefCountedPtr socket_node, + const grpc_core::RefCountedPtr& + socket_node, grpc_resource_user* resource_user) { size_t num_registered_methods; size_t alloc; @@ -1166,7 +1172,12 @@ void grpc_server_setup_transport( chand->server = s; server_ref(s); chand->channel = channel; - chand->socket_node = std::move(socket_node); + if (socket_node != nullptr) { + chand->channelz_socket_uuid = socket_node->uuid(); + s->channelz_server->AddChildSocket(socket_node); + } else { + chand->channelz_socket_uuid = 0; + } size_t cq_idx; for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) { @@ -1241,19 +1252,6 @@ void grpc_server_setup_transport( grpc_transport_perform_op(transport, op); } -void grpc_server_populate_server_sockets( - grpc_server* s, grpc_core::channelz::ChildSocketsList* server_sockets, - intptr_t start_idx) { - gpr_mu_lock(&s->mu_global); - channel_data* c = nullptr; - for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) { - server_sockets->push_back(c->socket_node); - } - } - gpr_mu_unlock(&s->mu_global); -} - void grpc_server_populate_listen_sockets( grpc_server* server, grpc_core::channelz::ChildRefsList* listen_sockets) { gpr_mu_lock(&server->mu_global); diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 393bb242148..926a5825006 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -47,14 +47,10 @@ void grpc_server_add_listener(grpc_server* server, void* listener, void grpc_server_setup_transport( grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - grpc_core::RefCountedPtr socket_node, + const grpc_core::RefCountedPtr& + socket_node, grpc_resource_user* resource_user = nullptr); -/* fills in the uuids of all sockets used for connections on this server */ -void grpc_server_populate_server_sockets( - grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets, - intptr_t start_idx); - /* fills in the uuids of all listen sockets on this server */ void grpc_server_populate_listen_sockets( grpc_server* server, grpc_core::channelz::ChildRefsList* listen_sockets); From b1d73a01f15ef7de1aa3da25c2a62be0b97f2087 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 24 Jun 2019 15:15:26 -0700 Subject: [PATCH 636/676] Removed duplicate static table from hpack table. Removed an or instruction for every usage of static grpc metadata. Inlined hpack table lookups for static metadata. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This leads to faster hpack parser creation: BM_HpackParserInitDestroy 5.32µs ± 1% 0.06µs ± 1% -98.91% (p=0.000 n=18+19) And slightly faster parsing: BM_HpackParserParseHeader 456ns ± 1% 435ns ± 1% -4.74% (p=0.000 n=18+19) BM_HpackParserParseHeader 1.06µs ± 2% 1.04µs ± 2% -1.82% (p=0.000 n=19+20) It also yields a slight (0.5 - 1.0 microsecond) reduction in CPU time for fullstack unary pingpong: BM_UnaryPingPong/0/512 [polls/iter:3.0001 ] 23.9µs ± 2% 23.0µs ± 1% -3.63% (p=0.002 n=6+6) BM_UnaryPingPong/0/32768 [polls/iter:3.00015 ] 35.1µs ± 1% 34.2µs ± 1% -2.57% (p=0.036 n=5+3) BM_UnaryPingPong/8/0 [polls/iter:3.00011 ] 21.7µs ± 3% 21.2µs ± 2% -2.44% (p=0.017 n=6+5) --- .../chttp2/transport/hpack_parser.cc | 1 - .../transport/chttp2/transport/hpack_table.cc | 173 +------ .../transport/chttp2/transport/hpack_table.h | 56 ++- src/core/lib/transport/static_metadata.cc | 441 ++++++++++++++++++ src/core/lib/transport/static_metadata.h | 353 ++++---------- .../transport/chttp2/hpack_parser_test.cc | 4 + .../core/transport/chttp2/hpack_table_test.cc | 4 - test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 7 + tools/codegen/core/gen_static_metadata.py | 32 +- 9 files changed, 627 insertions(+), 444 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index efbd997e994..616d6c56148 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -1559,7 +1559,6 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p) { p->value.data.copied.length = 0; p->dynamic_table_update_allowed = 2; p->last_error = GRPC_ERROR_NONE; - grpc_chttp2_hptbl_init(&p->table); } void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p) { diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index 9d1ac4b370f..f86332c6bc3 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -35,179 +35,18 @@ extern grpc_core::TraceFlag grpc_http_trace; -static struct { - const char* key; - const char* value; -} static_table[] = { - /* 0: */ - {nullptr, nullptr}, - /* 1: */ - {":authority", ""}, - /* 2: */ - {":method", "GET"}, - /* 3: */ - {":method", "POST"}, - /* 4: */ - {":path", "/"}, - /* 5: */ - {":path", "/index.html"}, - /* 6: */ - {":scheme", "http"}, - /* 7: */ - {":scheme", "https"}, - /* 8: */ - {":status", "200"}, - /* 9: */ - {":status", "204"}, - /* 10: */ - {":status", "206"}, - /* 11: */ - {":status", "304"}, - /* 12: */ - {":status", "400"}, - /* 13: */ - {":status", "404"}, - /* 14: */ - {":status", "500"}, - /* 15: */ - {"accept-charset", ""}, - /* 16: */ - {"accept-encoding", "gzip, deflate"}, - /* 17: */ - {"accept-language", ""}, - /* 18: */ - {"accept-ranges", ""}, - /* 19: */ - {"accept", ""}, - /* 20: */ - {"access-control-allow-origin", ""}, - /* 21: */ - {"age", ""}, - /* 22: */ - {"allow", ""}, - /* 23: */ - {"authorization", ""}, - /* 24: */ - {"cache-control", ""}, - /* 25: */ - {"content-disposition", ""}, - /* 26: */ - {"content-encoding", ""}, - /* 27: */ - {"content-language", ""}, - /* 28: */ - {"content-length", ""}, - /* 29: */ - {"content-location", ""}, - /* 30: */ - {"content-range", ""}, - /* 31: */ - {"content-type", ""}, - /* 32: */ - {"cookie", ""}, - /* 33: */ - {"date", ""}, - /* 34: */ - {"etag", ""}, - /* 35: */ - {"expect", ""}, - /* 36: */ - {"expires", ""}, - /* 37: */ - {"from", ""}, - /* 38: */ - {"host", ""}, - /* 39: */ - {"if-match", ""}, - /* 40: */ - {"if-modified-since", ""}, - /* 41: */ - {"if-none-match", ""}, - /* 42: */ - {"if-range", ""}, - /* 43: */ - {"if-unmodified-since", ""}, - /* 44: */ - {"last-modified", ""}, - /* 45: */ - {"link", ""}, - /* 46: */ - {"location", ""}, - /* 47: */ - {"max-forwards", ""}, - /* 48: */ - {"proxy-authenticate", ""}, - /* 49: */ - {"proxy-authorization", ""}, - /* 50: */ - {"range", ""}, - /* 51: */ - {"referer", ""}, - /* 52: */ - {"refresh", ""}, - /* 53: */ - {"retry-after", ""}, - /* 54: */ - {"server", ""}, - /* 55: */ - {"set-cookie", ""}, - /* 56: */ - {"strict-transport-security", ""}, - /* 57: */ - {"transfer-encoding", ""}, - /* 58: */ - {"user-agent", ""}, - /* 59: */ - {"vary", ""}, - /* 60: */ - {"via", ""}, - /* 61: */ - {"www-authenticate", ""}, -}; - -static uint32_t entries_for_bytes(uint32_t bytes) { - return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / - GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; -} - -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl) { - size_t i; - - memset(tbl, 0, sizeof(*tbl)); - tbl->current_table_bytes = tbl->max_bytes = - GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE; - tbl->max_entries = tbl->cap_entries = - entries_for_bytes(tbl->current_table_bytes); - tbl->ents = static_cast( - gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries)); - memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries); - for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - tbl->static_ents[i - 1] = grpc_mdelem_from_slices( - grpc_slice_intern( - grpc_slice_from_static_string_internal(static_table[i].key)), - grpc_slice_intern( - grpc_slice_from_static_string_internal(static_table[i].value))); - } -} - void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl) { size_t i; - for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - GRPC_MDELEM_UNREF(tbl->static_ents[i]); - } for (i = 0; i < tbl->num_ents; i++) { GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]); } gpr_free(tbl->ents); + tbl->ents = nullptr; } -grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, - uint32_t tbl_index) { - /* Static table comes first, just return an entry from it */ - if (tbl_index <= GRPC_CHTTP2_LAST_STATIC_ENTRY) { - return tbl->static_ents[tbl_index - 1]; - } - /* Otherwise, find the value in the list of valid entries */ +grpc_mdelem grpc_chttp2_hptbl_lookup_dynamic_index(const grpc_chttp2_hptbl* tbl, + uint32_t tbl_index) { + /* Not static - find the value in the list of valid entries */ tbl_index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1); if (tbl_index < tbl->num_ents) { uint32_t offset = @@ -280,7 +119,7 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, evict1(tbl); } tbl->current_table_bytes = bytes; - tbl->max_entries = entries_for_bytes(bytes); + tbl->max_entries = grpc_chttp2_hptbl::entries_for_bytes(bytes); if (tbl->max_entries > tbl->cap_entries) { rebuild_ents(tbl, GPR_MAX(tbl->max_entries, 2 * tbl->cap_entries)); } else if (tbl->max_entries < tbl->cap_entries / 3) { @@ -350,7 +189,7 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( /* See if the string is in the static table */ for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) { - grpc_mdelem ent = tbl->static_ents[i]; + grpc_mdelem ent = grpc_static_mdelem_manifested[i]; if (!grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDKEY(ent))) continue; r.index = i + 1u; r.has_value = grpc_slice_eq(GRPC_MDVALUE(md), GRPC_MDVALUE(ent)); diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h index 38f8bdda6ae..699b7eccaf2 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.h +++ b/src/core/ext/transport/chttp2/transport/hpack_table.h @@ -22,6 +22,7 @@ #include #include +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" @@ -46,32 +47,45 @@ #endif /* hpack decoder table */ -typedef struct { +struct grpc_chttp2_hptbl { + static uint32_t entries_for_bytes(uint32_t bytes) { + return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; + } + static constexpr uint32_t kInitialCapacity = + (GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - + 1) / + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD; + + grpc_chttp2_hptbl() { + GPR_DEBUG_ASSERT(!ents); + constexpr uint32_t AllocSize = sizeof(*ents) * kInitialCapacity; + ents = static_cast(gpr_malloc(AllocSize)); + memset(ents, 0, AllocSize); + } + /* the first used entry in ents */ - uint32_t first_ent; + uint32_t first_ent = 0; /* how many entries are in the table */ - uint32_t num_ents; + uint32_t num_ents = 0; /* the amount of memory used by the table, according to the hpack algorithm */ - uint32_t mem_used; + uint32_t mem_used = 0; /* the max memory allowed to be used by the table, according to the hpack algorithm */ - uint32_t max_bytes; + uint32_t max_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE; /* the currently agreed size of the table, according to the hpack algorithm */ - uint32_t current_table_bytes; + uint32_t current_table_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE; /* Maximum number of entries we could possibly fit in the table, given defined overheads */ - uint32_t max_entries; + uint32_t max_entries = kInitialCapacity; /* Number of entries allocated in ents */ - uint32_t cap_entries; + uint32_t cap_entries = kInitialCapacity; /* a circular buffer of headers - this is stored in the opposite order to what hpack specifies, in order to simplify table management a little... meaning lookups need to SUBTRACT from the end position */ - grpc_mdelem* ents; - grpc_mdelem static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY]; -} grpc_chttp2_hptbl; + grpc_mdelem* ents = nullptr; +}; -/* initialize a hpack table */ -void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl* tbl); void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl* tbl); void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl, uint32_t max_bytes); @@ -79,8 +93,20 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl, uint32_t bytes); /* lookup a table entry based on its hpack index */ -grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, - uint32_t index); +grpc_mdelem grpc_chttp2_hptbl_lookup_dynamic_index(const grpc_chttp2_hptbl* tbl, + uint32_t tbl_index); +inline grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, + uint32_t index) { + /* Static table comes first, just return an entry from it. + NB: This imposes the constraint that the first + GRPC_CHTTP2_LAST_STATIC_ENTRY entries in the core static metadata table + must follow the hpack standard. If that changes, we *must* not rely on + reading the core static metadata table here; at that point we'd need our + own singleton static metadata in the correct order. */ + return index <= GRPC_CHTTP2_LAST_STATIC_ENTRY + ? grpc_static_mdelem_manifested[index - 1] + : grpc_chttp2_hptbl_lookup_dynamic_index(tbl, index); +} /* add a table entry to the index */ grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl, grpc_mdelem md) GRPC_MUST_USE_RESULT; diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 5887e3515fb..8b0a6f482d7 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -337,6 +337,447 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}, }; +/* Warning: the core static metadata currently operates under the soft +constraint that the first GRPC_CHTTP2_LAST_STATIC_ENTRY (61) entries must +contain metadata specified by the http2 hpack standard. The CHTTP2 transport +reads the core metadata with this assumption in mind. If the order of the core +static metadata is to be changed, then the CHTTP2 transport must be changed as +well to stop relying on the core metadata. */ + +grpc_mdelem grpc_static_mdelem_manifested[GRPC_STATIC_MDELEM_COUNT] = { + // clang-format off + /* GRPC_MDELEM_AUTHORITY_EMPTY: + ":authority": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[0].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_METHOD_GET: + ":method": "GET" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[1].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_METHOD_POST: + ":method": "POST" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[2].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_PATH_SLASH: + ":path": "/" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[3].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML: + ":path": "/index.html" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[4].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_SCHEME_HTTP: + ":scheme": "http" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[5].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_SCHEME_HTTPS: + ":scheme": "https" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[6].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_200: + ":status": "200" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[7].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_204: + ":status": "204" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[8].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_206: + ":status": "206" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[9].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_304: + ":status": "304" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[10].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_400: + ":status": "400" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[11].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_404: + ":status": "404" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[12].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STATUS_500: + ":status": "500" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[13].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_CHARSET_EMPTY: + "accept-charset": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[14].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE: + "accept-encoding": "gzip, deflate" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[15].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY: + "accept-language": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[16].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_RANGES_EMPTY: + "accept-ranges": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[17].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_EMPTY: + "accept": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[18].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY: + "access-control-allow-origin": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[19].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_AGE_EMPTY: + "age": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[20].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ALLOW_EMPTY: + "allow": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[21].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_AUTHORIZATION_EMPTY: + "authorization": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[22].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CACHE_CONTROL_EMPTY: + "cache-control": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[23].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY: + "content-disposition": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[24].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_ENCODING_EMPTY: + "content-encoding": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[25].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY: + "content-language": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[26].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_LENGTH_EMPTY: + "content-length": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[27].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_LOCATION_EMPTY: + "content-location": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[28].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_RANGE_EMPTY: + "content-range": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[29].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_TYPE_EMPTY: + "content-type": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[30].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_COOKIE_EMPTY: + "cookie": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[31].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_DATE_EMPTY: + "date": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[32].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ETAG_EMPTY: + "etag": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[33].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_EXPECT_EMPTY: + "expect": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[34].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_EXPIRES_EMPTY: + "expires": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[35].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_FROM_EMPTY: + "from": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[36].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_HOST_EMPTY: + "host": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[37].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_IF_MATCH_EMPTY: + "if-match": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[38].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY: + "if-modified-since": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[39].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_IF_NONE_MATCH_EMPTY: + "if-none-match": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[40].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_IF_RANGE_EMPTY: + "if-range": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[41].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY: + "if-unmodified-since": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[42].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_LAST_MODIFIED_EMPTY: + "last-modified": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[43].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_LINK_EMPTY: + "link": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[44].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_LOCATION_EMPTY: + "location": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[45].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_MAX_FORWARDS_EMPTY: + "max-forwards": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[46].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY: + "proxy-authenticate": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[47].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY: + "proxy-authorization": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[48].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_RANGE_EMPTY: + "range": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[49].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_REFERER_EMPTY: + "referer": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[50].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_REFRESH_EMPTY: + "refresh": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[51].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_RETRY_AFTER_EMPTY: + "retry-after": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[52].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_SERVER_EMPTY: + "server": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[53].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_SET_COOKIE_EMPTY: + "set-cookie": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[54].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY: + "strict-transport-security": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[55].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_TRANSFER_ENCODING_EMPTY: + "transfer-encoding": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[56].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_USER_AGENT_EMPTY: + "user-agent": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[57].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_VARY_EMPTY: + "vary": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[58].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_VIA_EMPTY: + "via": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[59].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY: + "www-authenticate": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[60].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_STATUS_0: + "grpc-status": "0" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[61].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_STATUS_1: + "grpc-status": "1" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[62].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_STATUS_2: + "grpc-status": "2" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[63].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ENCODING_IDENTITY: + "grpc-encoding": "identity" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[64].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ENCODING_GZIP: + "grpc-encoding": "gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[65].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ENCODING_DEFLATE: + "grpc-encoding": "deflate" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[66].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_TE_TRAILERS: + "te": "trailers" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[67].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC: + "content-type": "application/grpc" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[68].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_SCHEME_GRPC: + ":scheme": "grpc" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[69].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_METHOD_PUT: + ":method": "PUT" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[70].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_ENCODING_EMPTY: + "accept-encoding": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[71].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_ENCODING_IDENTITY: + "content-encoding": "identity" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[72].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_CONTENT_ENCODING_GZIP: + "content-encoding": "gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[73].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_LB_TOKEN_EMPTY: + "lb-token": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[74].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_LB_COST_BIN_EMPTY: + "lb-cost-bin": "" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[75].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY: + "grpc-accept-encoding": "identity" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[76].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE: + "grpc-accept-encoding": "deflate" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[77].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE: + "grpc-accept-encoding": "identity,deflate" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[78].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP: + "grpc-accept-encoding": "gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[79].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP: + "grpc-accept-encoding": "identity,gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[80].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP: + "grpc-accept-encoding": "deflate,gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[81].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP: + "grpc-accept-encoding": "identity,deflate,gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[82].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY: + "accept-encoding": "identity" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[83].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_ENCODING_GZIP: + "accept-encoding": "gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[84].data(), + GRPC_MDELEM_STORAGE_STATIC), + /* GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP: + "accept-encoding": "identity,gzip" */ + GRPC_MAKE_MDELEM( + &grpc_static_mdelem_table[85].data(), + GRPC_MDELEM_STORAGE_STATIC) + // clang-format on +}; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 800ee04d6f9..458e87d30a7 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -272,350 +272,195 @@ extern grpc_slice_refcount extern grpc_core::StaticMetadata grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; +extern grpc_mdelem grpc_static_mdelem_manifested[GRPC_STATIC_MDELEM_COUNT]; /* ":authority": "" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AUTHORITY_EMPTY (grpc_static_mdelem_manifested[0]) /* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_GET (grpc_static_mdelem_manifested[1]) /* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_POST (grpc_static_mdelem_manifested[2]) /* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PATH_SLASH (grpc_static_mdelem_manifested[3]) /* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (grpc_static_mdelem_manifested[4]) /* ":scheme": "http" */ -#define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_HTTP (grpc_static_mdelem_manifested[5]) /* ":scheme": "https" */ -#define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_HTTPS (grpc_static_mdelem_manifested[6]) /* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_200 (grpc_static_mdelem_manifested[7]) /* ":status": "204" */ -#define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_204 (grpc_static_mdelem_manifested[8]) /* ":status": "206" */ -#define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_206 (grpc_static_mdelem_manifested[9]) /* ":status": "304" */ -#define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_304 (grpc_static_mdelem_manifested[10]) /* ":status": "400" */ -#define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_400 (grpc_static_mdelem_manifested[11]) /* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_404 (grpc_static_mdelem_manifested[12]) /* ":status": "500" */ -#define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STATUS_500 (grpc_static_mdelem_manifested[13]) /* "accept-charset": "" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (grpc_static_mdelem_manifested[14]) /* "accept-encoding": "gzip, deflate" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (grpc_static_mdelem_manifested[15]) /* "accept-language": "" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (grpc_static_mdelem_manifested[16]) /* "accept-ranges": "" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (grpc_static_mdelem_manifested[17]) /* "accept": "" */ -#define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_EMPTY (grpc_static_mdelem_manifested[18]) /* "access-control-allow-origin": "" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (grpc_static_mdelem_manifested[19]) /* "age": "" */ -#define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AGE_EMPTY (grpc_static_mdelem_manifested[20]) /* "allow": "" */ -#define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ALLOW_EMPTY (grpc_static_mdelem_manifested[21]) /* "authorization": "" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_AUTHORIZATION_EMPTY (grpc_static_mdelem_manifested[22]) /* "cache-control": "" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (grpc_static_mdelem_manifested[23]) /* "content-disposition": "" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ + (grpc_static_mdelem_manifested[24]) /* "content-encoding": "" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (grpc_static_mdelem_manifested[25]) /* "content-language": "" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (grpc_static_mdelem_manifested[26]) /* "content-length": "" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (grpc_static_mdelem_manifested[27]) /* "content-location": "" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (grpc_static_mdelem_manifested[28]) /* "content-range": "" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (grpc_static_mdelem_manifested[29]) /* "content-type": "" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (grpc_static_mdelem_manifested[30]) /* "cookie": "" */ -#define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_COOKIE_EMPTY (grpc_static_mdelem_manifested[31]) /* "date": "" */ -#define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_DATE_EMPTY (grpc_static_mdelem_manifested[32]) /* "etag": "" */ -#define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ETAG_EMPTY (grpc_static_mdelem_manifested[33]) /* "expect": "" */ -#define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_EXPECT_EMPTY (grpc_static_mdelem_manifested[34]) /* "expires": "" */ -#define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_EXPIRES_EMPTY (grpc_static_mdelem_manifested[35]) /* "from": "" */ -#define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_FROM_EMPTY (grpc_static_mdelem_manifested[36]) /* "host": "" */ -#define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_HOST_EMPTY (grpc_static_mdelem_manifested[37]) /* "if-match": "" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_MATCH_EMPTY (grpc_static_mdelem_manifested[38]) /* "if-modified-since": "" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (grpc_static_mdelem_manifested[39]) /* "if-none-match": "" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (grpc_static_mdelem_manifested[40]) /* "if-range": "" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_RANGE_EMPTY (grpc_static_mdelem_manifested[41]) /* "if-unmodified-since": "" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ + (grpc_static_mdelem_manifested[42]) /* "last-modified": "" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (grpc_static_mdelem_manifested[43]) /* "link": "" */ -#define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LINK_EMPTY (grpc_static_mdelem_manifested[44]) /* "location": "" */ -#define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LOCATION_EMPTY (grpc_static_mdelem_manifested[45]) /* "max-forwards": "" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (grpc_static_mdelem_manifested[46]) /* "proxy-authenticate": "" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (grpc_static_mdelem_manifested[47]) /* "proxy-authorization": "" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ + (grpc_static_mdelem_manifested[48]) /* "range": "" */ -#define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_RANGE_EMPTY (grpc_static_mdelem_manifested[49]) /* "referer": "" */ -#define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_REFERER_EMPTY (grpc_static_mdelem_manifested[50]) /* "refresh": "" */ -#define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_REFRESH_EMPTY (grpc_static_mdelem_manifested[51]) /* "retry-after": "" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY (grpc_static_mdelem_manifested[52]) /* "server": "" */ -#define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SERVER_EMPTY (grpc_static_mdelem_manifested[53]) /* "set-cookie": "" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SET_COOKIE_EMPTY (grpc_static_mdelem_manifested[54]) /* "strict-transport-security": "" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (grpc_static_mdelem_manifested[55]) /* "transfer-encoding": "" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (grpc_static_mdelem_manifested[56]) /* "user-agent": "" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_USER_AGENT_EMPTY (grpc_static_mdelem_manifested[57]) /* "vary": "" */ -#define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_VARY_EMPTY (grpc_static_mdelem_manifested[58]) /* "via": "" */ -#define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_VIA_EMPTY (grpc_static_mdelem_manifested[59]) /* "www-authenticate": "" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (grpc_static_mdelem_manifested[60]) /* "grpc-status": "0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_0 (grpc_static_mdelem_manifested[61]) /* "grpc-status": "1" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_1 (grpc_static_mdelem_manifested[62]) /* "grpc-status": "2" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_STATUS_2 (grpc_static_mdelem_manifested[63]) /* "grpc-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (grpc_static_mdelem_manifested[64]) /* "grpc-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_GZIP (grpc_static_mdelem_manifested[65]) /* "grpc-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (grpc_static_mdelem_manifested[66]) /* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_TE_TRAILERS (grpc_static_mdelem_manifested[67]) /* "content-type": "application/grpc" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (grpc_static_mdelem_manifested[68]) /* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_SCHEME_GRPC (grpc_static_mdelem_manifested[69]) /* ":method": "PUT" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_METHOD_PUT (grpc_static_mdelem_manifested[70]) /* "accept-encoding": "" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (grpc_static_mdelem_manifested[71]) /* "content-encoding": "identity" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (grpc_static_mdelem_manifested[72]) /* "content-encoding": "gzip" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP (grpc_static_mdelem_manifested[73]) /* "lb-token": "" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LB_TOKEN_EMPTY (grpc_static_mdelem_manifested[74]) /* "lb-cost-bin": "" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_LB_COST_BIN_EMPTY (grpc_static_mdelem_manifested[75]) /* "grpc-accept-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (grpc_static_mdelem_manifested[76]) /* "grpc-accept-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ + (grpc_static_mdelem_manifested[77]) /* "grpc-accept-encoding": "identity,deflate" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) + (grpc_static_mdelem_manifested[78]) /* "grpc-accept-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ + (grpc_static_mdelem_manifested[79]) /* "grpc-accept-encoding": "identity,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) + (grpc_static_mdelem_manifested[80]) /* "grpc-accept-encoding": "deflate,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) + (grpc_static_mdelem_manifested[81]) /* "grpc-accept-encoding": "identity,deflate,gzip" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) + (grpc_static_mdelem_manifested[82]) /* "accept-encoding": "identity" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY (grpc_static_mdelem_manifested[83]) /* "accept-encoding": "gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP (grpc_static_mdelem_manifested[84]) /* "accept-encoding": "identity,gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85].data(), \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (grpc_static_mdelem_manifested[85]) grpc_mdelem grpc_static_mdelem_for_static_strings(intptr_t a, intptr_t b); typedef enum { diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc index 882ad726b5a..8be7dc17ed1 100644 --- a/test/core/transport/chttp2/hpack_parser_test.cc +++ b/test/core/transport/chttp2/hpack_parser_test.cc @@ -102,6 +102,7 @@ static void test_vectors(grpc_slice_split_mode mode) { grpc_chttp2_hpack_parser_destroy(&parser); grpc_chttp2_hpack_parser_init(&parser); + new (&parser.table) grpc_chttp2_hptbl(); /* D.3.1 */ test_vector(&parser, mode, "8286 8441 0f77 7777 2e65 7861 6d70 6c65" @@ -122,6 +123,7 @@ static void test_vectors(grpc_slice_split_mode mode) { grpc_chttp2_hpack_parser_destroy(&parser); grpc_chttp2_hpack_parser_init(&parser); + new (&parser.table) grpc_chttp2_hptbl(); /* D.4.1 */ test_vector(&parser, mode, "8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4" @@ -142,6 +144,7 @@ static void test_vectors(grpc_slice_split_mode mode) { grpc_chttp2_hpack_parser_destroy(&parser); grpc_chttp2_hpack_parser_init(&parser); + new (&parser.table) grpc_chttp2_hptbl(); grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256); grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256); /* D.5.1 */ @@ -176,6 +179,7 @@ static void test_vectors(grpc_slice_split_mode mode) { grpc_chttp2_hpack_parser_destroy(&parser); grpc_chttp2_hpack_parser_init(&parser); + new (&parser.table) grpc_chttp2_hptbl(); grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256); grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256); /* D.6.1 */ diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc index c31975786f0..32b011b247b 100644 --- a/test/core/transport/chttp2/hpack_table_test.cc +++ b/test/core/transport/chttp2/hpack_table_test.cc @@ -48,8 +48,6 @@ static void test_static_lookup(void) { grpc_core::ExecCtx exec_ctx; grpc_chttp2_hptbl tbl; - grpc_chttp2_hptbl_init(&tbl); - LOG_TEST("test_static_lookup"); assert_index(&tbl, 1, ":authority", ""); assert_index(&tbl, 2, ":method", "GET"); @@ -125,7 +123,6 @@ static void test_many_additions(void) { LOG_TEST("test_many_additions"); grpc_core::ExecCtx exec_ctx; - grpc_chttp2_hptbl_init(&tbl); for (i = 0; i < 100000; i++) { grpc_mdelem elem; @@ -172,7 +169,6 @@ static void test_find(void) { LOG_TEST("test_find"); - grpc_chttp2_hptbl_init(&tbl); elem = grpc_mdelem_from_slices(grpc_slice_from_static_string("abc"), grpc_slice_from_static_string("xyz")); GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem) == GRPC_ERROR_NONE); diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index d0ed1da7671..1d2ddf13f6a 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -433,8 +433,15 @@ static void BM_HpackParserInitDestroy(benchmark::State& state) { TrackCounters track_counters; grpc_core::ExecCtx exec_ctx; grpc_chttp2_hpack_parser p; + // Initial destruction so we don't leak memory in the loop. + grpc_chttp2_hptbl_destroy(&p.table); while (state.KeepRunning()) { grpc_chttp2_hpack_parser_init(&p); + // Note that grpc_chttp2_hpack_parser_destroy frees the table dynamic + // elements so we need to recreate it here. In actual operation, + // grpc_core::New allocates the table once + // and for all. + new (&p.table) grpc_chttp2_hptbl(); grpc_chttp2_hpack_parser_destroy(&p); grpc_core::ExecCtx::Get()->Flush(); } diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index a149e001d75..95a545f5542 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -451,11 +451,37 @@ print >> H, ('extern grpc_core::StaticMetadata ' 'grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];') print >> H, ('extern uintptr_t ' 'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];') +print >> H, ('extern grpc_mdelem ' + 'grpc_static_mdelem_manifested[GRPC_STATIC_MDELEM_COUNT];') +print >> C, (''' +/* Warning: the core static metadata currently operates under the soft constraint +that the first GRPC_CHTTP2_LAST_STATIC_ENTRY (61) entries must contain +metadata specified by the http2 hpack standard. The CHTTP2 transport reads the +core metadata with this assumption in mind. If the order of the core static +metadata is to be changed, then the CHTTP2 transport must be changed as well to +stop relying on the core metadata. */ +''') +print >> C, ('grpc_mdelem ' + 'grpc_static_mdelem_manifested[GRPC_STATIC_MDELEM_COUNT] = {') +print >> C, '// clang-format off' +static_mds = [] for i, elem in enumerate(all_elems): + md_name = mangle(elem).upper() + md_human_readable = '"%s": "%s"' % elem + md_spec = ' /* %s: \n %s */\n' % (md_name, md_human_readable) + md_spec += ' GRPC_MAKE_MDELEM(\n' + md_spec += ((' &grpc_static_mdelem_table[%d].data(),\n' % i) + + ' GRPC_MDELEM_STORAGE_STATIC)') + static_mds.append(md_spec) +print >> C, ',\n'.join(static_mds) +print >> C, '// clang-format on' +print >> C, ('};') + +for i, elem in enumerate(all_elems): + md_name = mangle(elem).upper() print >> H, '/* "%s": "%s" */' % elem - print >> H, ( - '#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d].data(), ' - 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) + print >> H, ('#define %s (grpc_static_mdelem_manifested[%d])' % (md_name, + i)) print >> H print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' From 666d73e39cfaa7f40082c7234ca4f111a2178bce Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 3 Jul 2019 14:30:25 -0700 Subject: [PATCH 637/676] Cached metadata lookup for hpack_parser. --- .../chttp2/transport/hpack_parser.cc | 64 +++++++++++++++++-- .../transport/chttp2/transport/hpack_parser.h | 8 +++ 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index efbd997e994..f83f67ed195 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -779,6 +779,7 @@ static grpc_error* parse_indexed_field(grpc_chttp2_hpack_parser* p, const uint8_t* cur, const uint8_t* end) { p->dynamic_table_update_allowed = 0; p->index = (*cur) & 0x7f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ return finish_indexed_field(p, cur + 1, end); } @@ -791,17 +792,32 @@ static grpc_error* parse_indexed_field_x(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = 0x7f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ p->parsing.value = &p->index; return parse_value0(p, cur + 1, end); } +/* When finishing with a header, get the cached md element for this index. + This is set in parse_value_string(). We ensure (in debug mode) that the + cached metadata corresponds with the index we are examining. */ +static grpc_mdelem get_precomputed_md_for_idx(grpc_chttp2_hpack_parser* p) { + GPR_DEBUG_ASSERT(p->md_for_index.payload != 0); + GPR_DEBUG_ASSERT(static_cast(p->index) == p->precomputed_md_index); + grpc_mdelem md = p->md_for_index; + GPR_DEBUG_ASSERT(!GRPC_MDISNULL(md)); /* handled in string parsing */ + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ +#ifndef NDEBUG + p->precomputed_md_index = -1; +#endif + return md; +} + /* finish a literal header with incremental indexing */ static grpc_error* finish_lithdr_incidx(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(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX(); + grpc_mdelem md = get_precomputed_md_for_idx(p); grpc_error* err = on_hdr( p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), take_string(p, &p->value, true))); @@ -829,6 +845,7 @@ static grpc_error* parse_lithdr_incidx(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0x3f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ return parse_string_prefix(p, cur + 1, end); } @@ -842,6 +859,7 @@ static grpc_error* parse_lithdr_incidx_x(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = 0x3f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ p->parsing.value = &p->index; return parse_value0(p, cur + 1, end); } @@ -862,9 +880,8 @@ static grpc_error* parse_lithdr_incidx_v(grpc_chttp2_hpack_parser* p, static grpc_error* finish_lithdr_notidx(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(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX(); + grpc_mdelem md = get_precomputed_md_for_idx(p); grpc_error* err = on_hdr( p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), take_string(p, &p->value, false))); @@ -892,6 +909,7 @@ static grpc_error* parse_lithdr_notidx(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ return parse_string_prefix(p, cur + 1, end); } @@ -905,6 +923,7 @@ static grpc_error* parse_lithdr_notidx_x(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = 0xf; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ p->parsing.value = &p->index; return parse_value0(p, cur + 1, end); } @@ -925,9 +944,8 @@ static grpc_error* parse_lithdr_notidx_v(grpc_chttp2_hpack_parser* p, static grpc_error* finish_lithdr_nvridx(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(!GRPC_MDISNULL(md)); /* handled in string parsing */ GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX(); + grpc_mdelem md = get_precomputed_md_for_idx(p); grpc_error* err = on_hdr( p, grpc_mdelem_from_slices(grpc_slice_ref_internal(GRPC_MDKEY(md)), take_string(p, &p->value, false))); @@ -955,6 +973,7 @@ static grpc_error* parse_lithdr_nvridx(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = (*cur) & 0xf; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ return parse_string_prefix(p, cur + 1, end); } @@ -968,6 +987,7 @@ static grpc_error* parse_lithdr_nvridx_x(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed = 0; p->next_state = and_then; p->index = 0xf; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ p->parsing.value = &p->index; return parse_value0(p, cur + 1, end); } @@ -1007,6 +1027,7 @@ static grpc_error* parse_max_tbl_size(grpc_chttp2_hpack_parser* p, } p->dynamic_table_update_allowed--; p->index = (*cur) & 0x1f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ return finish_max_tbl_size(p, cur + 1, end); } @@ -1025,6 +1046,7 @@ static grpc_error* parse_max_tbl_size_x(grpc_chttp2_hpack_parser* p, p->dynamic_table_update_allowed--; p->next_state = and_then; p->index = 0x1f; + p->md_for_index.payload = 0; /* Invalidate cached md when index changes. */ p->parsing.value = &p->index; return parse_value0(p, cur + 1, end); } @@ -1499,6 +1521,23 @@ static bool is_binary_literal_header(grpc_chttp2_hpack_parser* p) { : p->key.data.referenced); } +/* Cache the metadata for the given index during initial parsing. This avoids a + pointless recomputation of the metadata when finishing a header. We read the + cached value in get_precomputed_md_for_idx(). */ +static void set_precomputed_md_idx(grpc_chttp2_hpack_parser* p, + grpc_mdelem md) { + GPR_DEBUG_ASSERT(p->md_for_index.payload == 0); + GPR_DEBUG_ASSERT(p->precomputed_md_index == -1); + p->md_for_index = md; +#ifndef NDEBUG + p->precomputed_md_index = p->index; +#endif +} + +/* Determines if a metadata element key associated with the current parser index + is a binary indexed header during string parsing. We'll need to revisit this + metadata when we're done parsing, so we cache the metadata for this index + here using set_precomputed_md_idx(). */ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p, bool* is) { grpc_mdelem elem = grpc_chttp2_hptbl_lookup(&p->table, p->index); @@ -1519,6 +1558,7 @@ static grpc_error* is_binary_indexed_header(grpc_chttp2_hpack_parser* p, * interned. * 4. Both static and interned element slices have non-null refcounts. */ *is = grpc_is_refcounted_slice_binary_header(GRPC_MDKEY(elem)); + set_precomputed_md_idx(p, elem); return GRPC_ERROR_NONE; } @@ -1557,6 +1597,18 @@ void grpc_chttp2_hpack_parser_init(grpc_chttp2_hpack_parser* p) { p->value.data.copied.str = nullptr; p->value.data.copied.capacity = 0; p->value.data.copied.length = 0; + /* Cached metadata for the current index the parser is handling. This is set + to 0 initially, invalidated when the index changes, and invalidated when it + is read (by get_precomputed_md_for_idx()). It is set during string parsing, + by set_precomputed_md_idx() - which is called by parse_value_string(). + The goal here is to avoid recomputing the metadata for the index when + finishing with a header as well as the initial parse. */ + p->md_for_index.payload = 0; +#ifndef NDEBUG + /* In debug mode, this ensures that the cached metadata we're reading is in + * fact correct for the index we are examining. */ + p->precomputed_md_index = -1; +#endif p->dynamic_table_update_allowed = 2; p->last_error = GRPC_ERROR_NONE; grpc_chttp2_hptbl_init(&p->table); diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 3dc8e13bea2..c5691244028 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -69,6 +69,14 @@ struct grpc_chttp2_hpack_parser { grpc_chttp2_hpack_parser_string value; /* parsed index */ uint32_t index; + /* When we parse a value string, we determine the metadata element for a + specific index, which we need again when we're finishing up with that + header. To avoid calculating the metadata element for that index a second + time at that stage, we cache (and invalidate) the element here. */ + grpc_mdelem md_for_index; +#ifndef NDEBUG + int64_t precomputed_md_index; +#endif /* length of source bytes for the currently parsing string */ uint32_t strlen; /* number of source bytes read for the currently parsing string */ From c8a277add49f15cee5dfbea0bc2ec82a160c70eb Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 15 Jul 2019 16:54:17 -0700 Subject: [PATCH 638/676] Several documentation fixes --- src/python/grpcio/grpc/__init__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index ac5192e0fed..a1df5fb161c 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -339,8 +339,7 @@ class RpcContext(six.with_metaclass(abc.ABCMeta)): callback: A no-parameter callable to be called on RPC termination. Returns: - bool: - True if the callback was added and will be called later; False if + True if the callback was added and will be called later; False if the callback was not added and will not be called (because the RPC already terminated or some other reason). """ @@ -1285,6 +1284,7 @@ class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)): class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)): """Describes an RPC that has just arrived for service. + Attributes: method: The method name of the RPC. invocation_metadata: The :term:`metadata` sent by the client. @@ -1381,12 +1381,10 @@ class Server(six.with_metaclass(abc.ABCMeta)): This method may only be called before starting the server. Args: - address: The address for which to open a port. - if the port is 0, or not specified in the address, then gRPC runtime - will choose a port. + address: The address for which to open a port. If the port is 0, + or not specified in the address, then gRPC runtime will choose a port. Returns: - integer: An integer port on which server will accept RPC requests. """ raise NotImplementedError() @@ -1404,7 +1402,6 @@ class Server(six.with_metaclass(abc.ABCMeta)): server_credentials: A ServerCredentials object. Returns: - integer: An integer port on which server will accept RPC requests. """ raise NotImplementedError() From 34c76f527d12d7f0fba739e41dcdb06d82d4910d Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Mon, 15 Jul 2019 17:58:51 -0700 Subject: [PATCH 639/676] Add default size 1 for thread pool --- src/core/lib/iomgr/executor/threadpool.cc | 3 ++ src/core/lib/iomgr/executor/threadpool.h | 3 +- test/core/iomgr/threadpool_test.cc | 45 +++++++++++++---------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index 166bf0a34a0..9bb1fd1d1cd 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -51,6 +51,9 @@ void ThreadPool::SharedThreadPoolConstructor() { // All worker threads in thread pool must be joinable. thread_options_.set_joinable(true); + // Create at least 1 worker threads. + if (num_threads_ <= 0) num_threads_ = 1; + queue_ = New(); threads_ = static_cast( gpr_zalloc(num_threads_ * sizeof(ThreadPoolWorker*))); diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index 3f79bbe9d08..e37f5727ced 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -101,7 +101,8 @@ class ThreadPoolWorker { class ThreadPool : public ThreadPoolInterface { public: // Creates a thread pool with size of "num_threads", with default thread name - // "ThreadPoolWorker" and all thread options set to default. + // "ThreadPoolWorker" and all thread options set to default. If the given size + // is 0 or less, there will be 1 worker threads created inside pool. ThreadPool(int num_threads); // Same as ThreadPool(int num_threads) constructor, except diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index 9c678fa4304..1219d25f3b7 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -20,10 +20,29 @@ #include "test/core/util/test_config.h" -const int kSmallThreadPoolSize = 20; -const int kLargeThreadPoolSize = 100; -const int kThreadSmallIter = 100; -const int kThreadLargeIter = 10000; +static const int kSmallThreadPoolSize = 20; +static const int kLargeThreadPoolSize = 100; +static const int kThreadSmallIter = 100; +static const int kThreadLargeIter = 10000; + +static void test_size_zero(void) { + gpr_log(GPR_INFO, "test_size_zero"); + grpc_core::ThreadPool* pool_size_zero = + grpc_core::New(0); + GPR_ASSERT(pool_size_zero->pool_capacity() == 1); + Delete(pool_size_zero); +} + +static void test_constructor_option(void) { + gpr_log(GPR_INFO, "test_constructor_option"); + // Tests options + grpc_core::Thread::Options options; + options.set_stack_size(192 * 1024); // Random non-default value + grpc_core::ThreadPool* pool = grpc_core::New( + 0, "test_constructor_option", options); + GPR_ASSERT(pool->thread_options().stack_size() == options.stack_size()); + Delete(pool); +} // Simple functor for testing. It will count how many times being called. class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { @@ -109,21 +128,6 @@ class WorkThread { grpc_core::Thread thd_; }; -static void test_constructor(void) { - // Size is 0 case - grpc_core::ThreadPool* pool_size_zero = - grpc_core::New(0); - GPR_ASSERT(pool_size_zero->pool_capacity() == 0); - Delete(pool_size_zero); - // Tests options - grpc_core::Thread::Options options; - options.set_stack_size(192 * 1024); // Random non-default value - grpc_core::ThreadPool* pool = - grpc_core::New(0, "test_constructor", options); - GPR_ASSERT(pool->thread_options().stack_size() == options.stack_size()); - Delete(pool); -} - static void test_multi_add(void) { gpr_log(GPR_INFO, "test_multi_add"); const int num_work_thds = 10; @@ -178,7 +182,8 @@ static void test_one_thread_FIFO(void) { int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); - test_constructor(); + test_size_zero(); + test_constructor_option(); test_add(); test_multi_add(); test_one_thread_FIFO(); From eb72215622aaa69e74dad4eb12d3030ab57455f2 Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Mon, 15 Jul 2019 18:16:54 -0700 Subject: [PATCH 640/676] Removed reference of GRPCConnectivityMonitor --- gRPC.podspec | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 7 ------- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 6 +----- src/objective-c/GRPCClient/private/GRPCHost.m | 1 - 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/gRPC.podspec b/gRPC.podspec index bbfd08f9774..7b253a2b2bb 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,8 +58,8 @@ Pod::Spec.new do |s| ss.header_mappings_dir = "#{src_dir}" ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" - ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" + ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}", "#{src_dir}/private/GRPCConnectivityMonitor.{h,m}" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 45b03e4b684..c3b06d6c72d 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -33,7 +33,6 @@ #import "private/GRPCCallInternal.h" #import "private/GRPCChannelPool.h" #import "private/GRPCCompletionQueue.h" -#import "private/GRPCConnectivityMonitor.h" #import "private/GRPCHost.h" #import "private/GRPCRequestHeaders.h" #import "private/GRPCWrappedCall.h" @@ -288,7 +287,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; GRPCCallSafety _callSafety; GRPCCallOptions *_callOptions; GRPCWrappedCall *_wrappedCall; - GRPCConnectivityMonitor *_connectivityMonitor; // The C gRPC library has less guarantees on the ordering of events than we // do. Particularly, in the face of errors, there's no ordering guarantee at @@ -494,8 +492,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } - (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; - __block GRPCWrappedCall *wrappedCall = _wrappedCall; dispatch_async(_callQueue, ^{ wrappedCall = nil; @@ -797,9 +793,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream != nil && enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; - } } // Now that the RPC has been initiated, request writes can start. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 60a33eda824..e8b6944d4b9 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -24,7 +24,6 @@ #import "GRPCChannelPool+Test.h" #import "GRPCChannelPool.h" #import "GRPCCompletionQueue.h" -#import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCInsecureChannelFactory.h" #import "GRPCSecureChannelFactory.h" @@ -218,15 +217,12 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; // Connectivity monitor is not required for CFStream char *enableCFStream = getenv(kCFStreamVarName); - if (enableCFStream == nil || enableCFStream[0] != '1') { - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; - } } return self; } - (void)dealloc { - [GRPCConnectivityMonitor unregisterObserver:self]; + } - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 24348c3aed7..63ffc927411 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -28,7 +28,6 @@ #import "../internal/GRPCCallOptions+Internal.h" #import "GRPCChannelFactory.h" #import "GRPCCompletionQueue.h" -#import "GRPCConnectivityMonitor.h" #import "GRPCCronetChannelFactory.h" #import "GRPCSecureChannelFactory.h" #import "NSDictionary+GRPC.h" From 3afb0b263565125a3c2b2a1634ae869b4f055a6d Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 15 Jul 2019 18:39:57 -0700 Subject: [PATCH 641/676] Fix fallback test breaking on mac bazel --- test/cpp/interop/grpclb_fallback_test.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/cpp/interop/grpclb_fallback_test.cc b/test/cpp/interop/grpclb_fallback_test.cc index 3622482b67d..38474b29749 100644 --- a/test/cpp/interop/grpclb_fallback_test.cc +++ b/test/cpp/interop/grpclb_fallback_test.cc @@ -18,6 +18,8 @@ #include +#include "src/core/lib/iomgr/port.h" + #include #include #include @@ -67,6 +69,7 @@ DEFINE_string( "slow_fallback_after_startup : fallback after startup due to LB/backend " "addresses becoming blackholed;\n"); +#ifdef GRPC_HAVE_TCP_USER_TIMEOUT using grpc::testing::GrpclbRouteType; using grpc::testing::SimpleRequest; using grpc::testing::SimpleResponse; @@ -270,3 +273,11 @@ int main(int argc, char** argv) { abort(); } } +#else +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + gpr_log(GPR_ERROR, + "This test requires TCP_USER_TIMEOUT, which isn't available"); + abort(); +} +#endif // GRPC_HAVE_TCP_USER_TIMEOUT From 881e0385296a1b99332eebaf2a4aa60f62d06ef9 Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Mon, 15 Jul 2019 18:55:12 -0700 Subject: [PATCH 642/676] Fixing duplicating problem --- gRPC-Core.podspec | 4 ++-- templates/gRPC-Core.podspec.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2dfcb311b5d..f309161fadb 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1387,7 +1387,7 @@ Pod::Spec.new do |s| # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\\n #include \\\n#else\\\n #include \\\n#endif;g' + sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) + sed -E -i '' 's;#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) END_OF_COMMAND end diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 652c4ed43f0..63baa01a27f 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -212,7 +212,7 @@ # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? s.prepare_command = <<-END_OF_COMMAND - find src/core/ -type f -print0 | xargs -0 -L1 sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' - find src/core/ -type f \\( -path '*.h' -or -path '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i '' 's;#include ;#if COCOAPODS\\\n #include \\\n#else\\\n #include \\\n#endif;g' + sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) + sed -E -i '' 's;#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) END_OF_COMMAND end From f9e6144692bd92cffe5690d5e9dfac92458acc17 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 12 Jul 2019 15:08:36 -0700 Subject: [PATCH 643/676] Avoid unnecessary ref of connected subchannel when creating subchannel call. --- .../filters/client_channel/client_channel.cc | 10 +-- .../health/health_check_client.cc | 6 +- .../ext/filters/client_channel/subchannel.cc | 67 ++++++++++--------- .../ext/filters/client_channel/subchannel.h | 31 ++++----- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0b612e67a33..257616a124e 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2157,9 +2157,8 @@ void CallData::DoRetry(grpc_call_element* elem, GPR_ASSERT(method_params_ != nullptr); const auto* retry_policy = method_params_->retry_policy(); GPR_ASSERT(retry_policy != nullptr); - // Reset subchannel call and connected subchannel. + // Reset subchannel call. subchannel_call_.reset(); - connected_subchannel_.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { @@ -3277,13 +3276,14 @@ void CallData::CreateSubchannelCall(grpc_call_element* elem) { ChannelData* chand = static_cast(elem->channel_data); const size_t parent_data_size = enable_retries_ ? sizeof(SubchannelCallRetryState) : 0; - const ConnectedSubchannel::CallArgs call_args = { - pollent_, path_, call_start_time_, deadline_, arena_, + SubchannelCall::Args call_args = { + std::move(connected_subchannel_), pollent_, path_, call_start_time_, + deadline_, arena_, // TODO(roth): When we implement hedging support, we will probably // need to use a separate call context for each subchannel call. call_context_, call_combiner_, parent_data_size}; grpc_error* error = GRPC_ERROR_NONE; - subchannel_call_ = connected_subchannel_->CreateCall(call_args, &error); + subchannel_call_ = SubchannelCall::Create(std::move(call_args), &error); if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, this, subchannel_call_.get(), grpc_error_string(error)); diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index faa2ba5b3b1..a6b910b5dad 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -310,7 +310,8 @@ void HealthCheckClient::CallState::Orphan() { } void HealthCheckClient::CallState::StartCall() { - ConnectedSubchannel::CallArgs args = { + SubchannelCall::Args args = { + health_check_client_->connected_subchannel_, &pollent_, GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH, gpr_now(GPR_CLOCK_MONOTONIC), // start_time @@ -321,8 +322,7 @@ void HealthCheckClient::CallState::StartCall() { 0, // parent_data_size }; grpc_error* error = GRPC_ERROR_NONE; - call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error) - .release(); + call_ = SubchannelCall::Create(std::move(args), &error).release(); // Register after-destruction callback. GRPC_CLOSURE_INIT(&after_call_stack_destruction_, AfterCallStackDestruction, this, grpc_schedule_on_exec_ctx); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b6ab47fb09d..c3521f46cee 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -117,14 +117,37 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -RefCountedPtr ConnectedSubchannel::CreateCall( - const CallArgs& args, grpc_error** error) { +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + +// +// SubchannelCall +// + +RefCountedPtr SubchannelCall::Create(Args args, + grpc_error** error) { const size_t allocation_size = - GetInitialCallSizeEstimate(args.parent_data_size); - RefCountedPtr call( - new (args.arena->Alloc(allocation_size)) - SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args)); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get()); + args.connected_subchannel->GetInitialCallSizeEstimate( + args.parent_data_size); + return RefCountedPtr(new (args.arena->Alloc( + allocation_size)) SubchannelCall(std::move(args), error)); +} + +SubchannelCall::SubchannelCall(Args args, grpc_error** error) + : connected_subchannel_(std::move(args.connected_subchannel)), + deadline_(args.deadline) { + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(this); const grpc_call_element_args call_args = { callstk, /* call_stack */ nullptr, /* server_transport_data */ @@ -135,38 +158,20 @@ RefCountedPtr ConnectedSubchannel::CreateCall( args.arena, /* arena */ args.call_combiner /* call_combiner */ }; - *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCall::Destroy, - call.get(), &call_args); + *error = grpc_call_stack_init(connected_subchannel_->channel_stack(), 1, + SubchannelCall::Destroy, this, &call_args); if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { const char* error_string = grpc_error_string(*error); gpr_log(GPR_ERROR, "error: %s", error_string); - return call; + return; } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); + auto* channelz_node = connected_subchannel_->channelz_subchannel(); + if (channelz_node != nullptr) { + channelz_node->RecordCallStarted(); } - return call; } -size_t ConnectedSubchannel::GetInitialCallSizeEstimate( - size_t parent_data_size) const { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); - if (parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } - return allocation_size; -} - -// -// SubchannelCall -// - void SubchannelCall::StartTransportStreamOpBatch( grpc_transport_stream_op_batch* batch) { GPR_TIMER_SCOPE("subchannel_call_process_op", 0); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 64d679af6c5..d1c4b7d1073 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -72,17 +72,6 @@ class SubchannelCall; class ConnectedSubchannel : public ConnectedSubchannelInterface { public: - struct CallArgs { - grpc_polling_entity* pollent; - grpc_slice path; - gpr_timespec start_time; - grpc_millis deadline; - Arena* arena; - grpc_call_context_element* context; - CallCombiner* call_combiner; - size_t parent_data_size; - }; - ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, RefCountedPtr channelz_subchannel); @@ -92,8 +81,6 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - RefCountedPtr CreateCall(const CallArgs& args, - grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } const grpc_channel_args* args() const override { return args_; } @@ -114,10 +101,18 @@ class ConnectedSubchannel : public ConnectedSubchannelInterface { // Implements the interface of RefCounted<>. class SubchannelCall { public: - SubchannelCall(RefCountedPtr connected_subchannel, - const ConnectedSubchannel::CallArgs& args) - : connected_subchannel_(std::move(connected_subchannel)), - deadline_(args.deadline) {} + struct Args { + RefCountedPtr connected_subchannel; + grpc_polling_entity* pollent; + grpc_slice path; + gpr_timespec start_time; + grpc_millis deadline; + Arena* arena; + grpc_call_context_element* context; + CallCombiner* call_combiner; + size_t parent_data_size; + }; + static RefCountedPtr Create(Args args, grpc_error** error); // Continues processing a transport stream op batch. void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch); @@ -150,6 +145,8 @@ class SubchannelCall { template friend class RefCountedPtr; + SubchannelCall(Args args, grpc_error** error); + // If channelz is enabled, intercepts recv_trailing so that we may check the // status and associate it to a subchannel. void MaybeInterceptRecvTrailingMetadata( From b58d2e84ab7412f54f30a88b698a74a3db344cb4 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 16 Jul 2019 10:45:08 -0400 Subject: [PATCH 644/676] Make sure there is at least a header in the frame storge of H2. grpc_chttp2_maybe_complete_recv_trailing_metadata() moves at least GRPC_HEADER_SIZE_IN_BYTES from the frame storage, whenever the frame storage is non-empty. Instead ensure that we have at least GRPC_HEADER_SIZE_IN_BYTES in the frame storage. This results in bugs detected by clusterfuzz in chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=984534 https://bugs.chromium.org/p/chromium/issues/detail?id=984478#c2 --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 3c9a8a2209f..43f2db1309f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2016,9 +2016,10 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t, * maybe decompress the next 5 bytes in the stream. */ if (s->stream_decompression_method == GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS) { - grpc_slice_buffer_move_first(&s->frame_storage, - GRPC_HEADER_SIZE_IN_BYTES, - &s->unprocessed_incoming_frames_buffer); + grpc_slice_buffer_move_first( + &s->frame_storage, + GPR_MIN(s->frame_storage.length, GRPC_HEADER_SIZE_IN_BYTES), + &s->unprocessed_incoming_frames_buffer); if (s->unprocessed_incoming_frames_buffer.length > 0) { s->unprocessed_incoming_frames_decompressed = true; pending_data = true; From a07b669ce6d3318f93af2670b4015a0d3a4b3409 Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Tue, 16 Jul 2019 10:55:30 -0700 Subject: [PATCH 645/676] Used a safer filter --- gRPC-Core.podspec | 4 ++-- templates/gRPC-Core.podspec.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f309161fadb..c3055ae15b9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1387,7 +1387,7 @@ Pod::Spec.new do |s| # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path? s.prepare_command = <<-END_OF_COMMAND - sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) - sed -E -i '' 's;#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) + sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) - sed -E -i '' 's;#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#if COCOAPODS==1' | grep 0$ | cut -d':' -f1) + sed -E -i '' 's;#include "(pb(_.*)?\\.h)";#if COCOAPODS==1\\\n #include \\\n#else\\\n #include "\\1"\\\n#endif;g' $(find src/core -type f -print | xargs grep -H -c '#include ;#if COCOAPODS==1\\\n #include \\\n#else\\\n #include \\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include Date: Tue, 2 Jul 2019 15:01:40 -0700 Subject: [PATCH 646/676] Fix the entry condition of Bazel hack --- .../grpcio_tests/tests/bazel_namespace_package_hack.py | 5 +++++ tools/bazel.rc | 1 + 2 files changed, 6 insertions(+) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index 006a3deecb4..994a8e1e800 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -16,6 +16,8 @@ import os import site import sys +_GRPC_BAZEL_RUNTIME_ENV = "GRPC_BAZEL_RUNTIME" + # TODO(https://github.com/bazelbuild/bazel/issues/6844) Bazel failed to # interpret namespace packages correctly. This monkey patch will force the @@ -24,6 +26,9 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" + # Only run within our Bazel environment + if not os.environ.get(_GRPC_BAZEL_RUNTIME_ENV): + return items = [] for item in sys.path: if os.path.exists(item): diff --git a/tools/bazel.rc b/tools/bazel.rc index 4bd3a5d7445..7a716e85088 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -5,6 +5,7 @@ build --client_env=CC=clang build --copt=-DGRPC_BAZEL_BUILD +build --action_env=GRPC_BAZEL_RUNTIME=1 build:opt --compilation_mode=opt build:opt --copt=-Wframe-larger-than=16384 From 603054a29a68c0eb993180e8f687cc0cafdb0113 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Tue, 16 Jul 2019 18:25:30 -0700 Subject: [PATCH 647/676] Modify locality --- src/core/lib/iomgr/executor/threadpool.cc | 2 +- src/core/lib/iomgr/executor/threadpool.h | 2 +- test/core/iomgr/threadpool_test.cc | 40 +++++++++++------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index 9bb1fd1d1cd..f0df1bd18eb 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -51,7 +51,7 @@ void ThreadPool::SharedThreadPoolConstructor() { // All worker threads in thread pool must be joinable. thread_options_.set_joinable(true); - // Create at least 1 worker threads. + // Create at least 1 worker thread. if (num_threads_ <= 0) num_threads_ = 1; queue_ = New(); diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index e37f5727ced..78f61a3139c 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -102,7 +102,7 @@ class ThreadPool : public ThreadPoolInterface { public: // Creates a thread pool with size of "num_threads", with default thread name // "ThreadPoolWorker" and all thread options set to default. If the given size - // is 0 or less, there will be 1 worker threads created inside pool. + // is 0 or less, there will be 1 worker thread created inside pool. ThreadPool(int num_threads); // Same as ThreadPool(int num_threads) constructor, except diff --git a/test/core/iomgr/threadpool_test.cc b/test/core/iomgr/threadpool_test.cc index 1219d25f3b7..ac94af170e2 100644 --- a/test/core/iomgr/threadpool_test.cc +++ b/test/core/iomgr/threadpool_test.cc @@ -66,26 +66,6 @@ class SimpleFunctorForAdd : public grpc_experimental_completion_queue_functor { grpc_core::Atomic count_{0}; }; -// Checks the given SimpleFunctorForAdd's count with a given number. -class SimpleFunctorCheckForAdd - : public grpc_experimental_completion_queue_functor { - public: - SimpleFunctorCheckForAdd(int ok, int* count) : count_(count) { - functor_run = &SimpleFunctorCheckForAdd::Run; - internal_success = ok; - } - ~SimpleFunctorCheckForAdd() {} - static void Run(struct grpc_experimental_completion_queue_functor* cb, - int ok) { - auto* callback = static_cast(cb); - (*callback->count_)++; - GPR_ASSERT(*callback->count_ == callback->internal_success); - } - - private: - int* count_; -}; - static void test_add(void) { gpr_log(GPR_INFO, "test_add"); grpc_core::ThreadPool* pool = @@ -157,6 +137,26 @@ static void test_multi_add(void) { gpr_log(GPR_DEBUG, "Done."); } +// Checks the current count with a given number. +class SimpleFunctorCheckForAdd + : public grpc_experimental_completion_queue_functor { + public: + SimpleFunctorCheckForAdd(int ok, int* count) : count_(count) { + functor_run = &SimpleFunctorCheckForAdd::Run; + internal_success = ok; + } + ~SimpleFunctorCheckForAdd() {} + static void Run(struct grpc_experimental_completion_queue_functor* cb, + int ok) { + auto* callback = static_cast(cb); + (*callback->count_)++; + GPR_ASSERT(*callback->count_ == callback->internal_success); + } + + private: + int* count_; +}; + static void test_one_thread_FIFO(void) { gpr_log(GPR_INFO, "test_one_thread_FIFO"); int counter = 0; From dfca76905d152477460b8e33e8249ce6a4c8f27f Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Tue, 16 Jul 2019 18:32:01 -0700 Subject: [PATCH 648/676] Removed unused variable enableCFStream --- src/objective-c/GRPCClient/GRPCCall.m | 3 --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index c3b06d6c72d..a9b112b5d52 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -790,9 +790,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; [self sendHeaders]; [self invokeCall]; - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); } // Now that the RPC has been initiated, request writes can start. diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index e8b6944d4b9..683e203ca31 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -214,9 +214,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; - (instancetype)initPrivate { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; - - // Connectivity monitor is not required for CFStream - char *enableCFStream = getenv(kCFStreamVarName); } return self; } From 12ededb237d3c58117fd7bb0dddec146ed2f6408 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 16 Jul 2019 14:22:16 -0700 Subject: [PATCH 649/676] Increase lower bound on DNS re-resolution period to 30 seconds --- .../client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../filters/client_channel/resolver/dns/native/dns_resolver.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 4e7bb5ec482..65f80525e54 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -144,7 +144,7 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args) arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); min_time_between_resolutions_ = - grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX}); + grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX}); // Enable SRV queries option arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES); enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false); diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index bc6d73acac7..629b7360a88 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -110,7 +110,7 @@ NativeDnsResolver::NativeDnsResolver(ResolverArgs args) const grpc_arg* arg = grpc_channel_args_find( args.args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); min_time_between_resolutions_ = - grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX}); + grpc_channel_arg_get_integer(arg, {1000 * 30, 0, INT_MAX}); interested_parties_ = grpc_pollset_set_create(); if (args.pollset_set != nullptr) { grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set); From 0ada8b68d344bcefb9349c5ffe0c2fbd5012a55a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 17 Jul 2019 14:10:03 +0200 Subject: [PATCH 650/676] add versioning guide --- doc/versioning.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 doc/versioning.md diff --git a/doc/versioning.md b/doc/versioning.md new file mode 100644 index 00000000000..e39334d1df1 --- /dev/null +++ b/doc/versioning.md @@ -0,0 +1,41 @@ +# gRPC Versioning Guide + +## Versioning Overview + +All gRPC implementations use a three-part version number (`vX.Y.Z`) and strictly follow [semantic versioning](https://semver.org/), which defines the semantics of major, minor and patch components of the version number. In addition to that, gRPC versions evolve according to these rules: +- **Major version bumps** only happen on rare occasions. In order to qualify for a major version bump, certain criteria described later in this document need to be met. Most importantly, a major version increase must not break wire compatibility with other gRPC implementations so that existing gRPC libraries remain fully interoperable. +- **Minor version bumps** happen approx. every 6 weeks as part of the normal release cycle as defined by the gRPC release process. A new release branch named vMAJOR.MINOR.PATCH) is cut every 6 weeks based on the [release schedule](https://github.com/grpc/grpc/blob/master/doc/grpc_release_schedule.md). +- **Patch version bump** corresponds to bugfixes done on release branch. + +There are also a few extra rules regarding adding new gRPC implementations (e.g. adding support for a new language) +- New implementations start at v0.x.y version they reaches 1.0, they are considered not ready for production workloads. Breaking API changes are allowed in the 0.x releases as the library is not considered stable yet. +- The "1.0" release has semantics of GA (generally available) and being production ready. Requirements to reach this milestone are at least these + - basic RPC features are feature complete and tested + - implementation is tested for interoperability with other languages + - Public API is declared stable +- Once a gRPC library reaches 1.0 (or higher version), the normal rules for versioning apply. + +## Policy for updating the major version number + +To avoid user confusion and simplify reasoning, the gRPC releases in different languages try to stay synchronized in terms of major and minor version (all languages follow the same release schedule). Nevertheless, because we also strictly follow semantic versioning, there are circumstances in which a gRPC implementation needs to break the version synchronicity and do a major version bump independently of other languages. + +### Situations when it's ok to do a major version bump +- **change forced by the language ecosystem:** when the language itself or its standard libraries that we depend on make a breaking change (something which is out of our control), reacting with updating gRPC APIs may be the only adequate response. +- **voluntary change:** Even in non-forced situations, there might be circumstances in which a breaking API change makes sense and represents a net win, but as a rule of thumb breaking changes are very disruptive for users, cause user fragmentation and incur high maintenance costs. Therefore, breaking API changes should be very rare events that need to be considered with extreme care and the bar for accepting such changes is intentionally set very high. + Example scenarios where a breaking API change might be adequate: + - fixing a security problem which requires changes to API (need to consider the non-breaking alternatives first) + - the change leads to very significant gains to security, usability or development. velocity. These gains need to be clearly documented and claims need to be supported by evidence (ideally by numbers). Costs to the ecosystem (impact on users, dev team etc.) need to be taken into account and the change still needs to be a net positive after subtracting the costs. + + All proposals to make a breaking change need to be documented as a gRFC document (in the grpc/proposal repository) that covers at least these areas: + - Description of the proposal including an explanation why the proposed change is one of the very rare events where a breaking change is introduced. + - Migration costs (= what does it mean for the users to migrate to the new API, what are the costs and risks associated with it) + - Pros of the change (what is gained and how) + - Cons of the change (e.g. user confusion, lost users and user trust, work needed, added maintenance costs) + - Plan for supporting users still using the old major version (in case migration to the new major version is not trivial or not everyone can migrate easily) + +Note that while major version bump allows changing APIs used by the users, it must not impact the interoperability of the implementation with other gRPC implementations and the previous major version released. That means that **no backward incompatible protocol changes are allowed**: old clients must continue interoperating correctly with new servers and new servers with old clients. + +### Situations that DON'T warrant a major version bump +- Because other languages do so. This is not a good enough reason because +doing a major version bump has high potential for disturbing and confusing the users of that language and fragmenting the user base and that is a bigger threat than having language implementations at different major version (provided the state is well documented). Having some languages at different major version seems to be unavoidable anyway (due to forced version bumps), unless we bump some languages artificially. +- "I don't like this API": In retrospect, some API decisions made in the past necessarily turn out more lucky than others, but without strong reasons that would be in favor of changing the API and without enough supporting evidence (see previous section), other strategy than making a breaking API change needs to be used. Possible options: Expand the API to make it useful again; mark API as deprecated while keeping its functionality and providing a new better API. From 170d3633f056a32f0934ef720d0c4c7af35bdef0 Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Wed, 17 Jul 2019 09:56:34 -0700 Subject: [PATCH 651/676] Removed source files GRPCConnectivityMonitor --- gRPC.podspec | 2 +- .../private/GRPCConnectivityMonitor.h | 47 ---------- .../private/GRPCConnectivityMonitor.m | 90 ------------------- 3 files changed, 1 insertion(+), 138 deletions(-) delete mode 100644 src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h delete mode 100644 src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m diff --git a/gRPC.podspec b/gRPC.podspec index 7b253a2b2bb..bbfd08f9774 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -58,8 +58,8 @@ Pod::Spec.new do |s| ss.header_mappings_dir = "#{src_dir}" ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}" + ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}" ss.private_header_files = "#{src_dir}/private/*.h", "#{src_dir}/internal/*.h" - ss.exclude_files = "#{src_dir}/GRPCCall+GID.{h,m}", "#{src_dir}/private/GRPCConnectivityMonitor.{h,m}" ss.dependency 'gRPC-Core', version end diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h deleted file mode 100644 index d4b49b1b28e..00000000000 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import -#import - -typedef NS_ENUM(NSInteger, GRPCConnectivityStatus) { - GRPCConnectivityUnknown = 0, - GRPCConnectivityNoNetwork = 1, - GRPCConnectivityCellular = 2, - GRPCConnectivityWiFi = 3, -}; - -extern NSString* _Nonnull kGRPCConnectivityNotification; - -// This interface monitors OS reachability interface for any network status -// change. Parties interested in these events should register themselves as -// observer. -@interface GRPCConnectivityMonitor : NSObject - -- (nonnull instancetype)init NS_UNAVAILABLE; - -// Register an object as observer of network status change. \a observer -// must have a notification method with one parameter of type -// (NSNotification *) and should pass it to parameter \a selector. The -// parameter of this notification method is not used for now. -+ (void)registerObserver:(_Nonnull id)observer selector:(_Nonnull SEL)selector; - -// Ungegister an object from observers of network status change. -+ (void)unregisterObserver:(_Nonnull id)observer; - -@end diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m deleted file mode 100644 index bb8618ff335..00000000000 --- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m +++ /dev/null @@ -1,90 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import "GRPCConnectivityMonitor.h" - -#include - -NSString *kGRPCConnectivityNotification = @"kGRPCConnectivityNotification"; - -static SCNetworkReachabilityRef reachability; -static GRPCConnectivityStatus currentStatus; - -// Aggregate information in flags into network status. -GRPCConnectivityStatus CalculateConnectivityStatus(SCNetworkReachabilityFlags flags) { - GRPCConnectivityStatus result = GRPCConnectivityUnknown; - if (((flags & kSCNetworkReachabilityFlagsReachable) == 0) || - ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0)) { - return GRPCConnectivityNoNetwork; - } - result = GRPCConnectivityWiFi; -#if TARGET_OS_IPHONE - if (flags & kSCNetworkReachabilityFlagsIsWWAN) { - return result = GRPCConnectivityCellular; - } -#endif - return result; -} - -static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, - void *info) { - GRPCConnectivityStatus newStatus = CalculateConnectivityStatus(flags); - - if (newStatus != currentStatus) { - [[NSNotificationCenter defaultCenter] postNotificationName:kGRPCConnectivityNotification - object:nil]; - currentStatus = newStatus; - } -} - -@implementation GRPCConnectivityMonitor - -+ (void)initialize { - if (self == [GRPCConnectivityMonitor self]) { - struct sockaddr_in addr = {0}; - addr.sin_len = sizeof(addr); - addr.sin_family = AF_INET; - reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&addr); - currentStatus = GRPCConnectivityUnknown; - - SCNetworkConnectionFlags flags; - if (SCNetworkReachabilityGetFlags(reachability, &flags)) { - currentStatus = CalculateConnectivityStatus(flags); - } - - SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; - if (!SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context) || - !SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), - kCFRunLoopCommonModes)) { - NSLog(@"gRPC connectivity monitor fail to set"); - } - } -} - -+ (void)registerObserver:(id)observer selector:(SEL)selector { - [[NSNotificationCenter defaultCenter] addObserver:observer - selector:selector - name:kGRPCConnectivityNotification - object:nil]; -} - -+ (void)unregisterObserver:(id)observer { - [[NSNotificationCenter defaultCenter] removeObserver:observer]; -} - -@end From 37126b54463d02b790f26aefc3e1c1294b80f212 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 17 Jul 2019 10:53:54 -0700 Subject: [PATCH 652/676] Lower min-time-between-resolutions for the goaway server test --- test/core/end2end/goaway_server_test.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 7e3b418cd94..5db2aebe9a1 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -185,13 +185,23 @@ int main(int argc, char** argv) { char* addr; grpc_channel_args client_args; - grpc_arg arg_array[1]; + grpc_arg arg_array[2]; arg_array[0].type = GRPC_ARG_INTEGER; arg_array[0].key = const_cast("grpc.testing.fixed_reconnect_backoff_ms"); arg_array[0].value.integer = 1000; + /* When this test brings down server1 and then brings up server2, + * the targetted server port number changes, and the client channel + * needs to re-resolve to pick this up. This test requires that + * happen within 10 seconds, but gRPC's DNS resolvers rate limit + * resolution attempts to at most once every 30 seconds by default. + * So we tweak it for this test. */ + arg_array[1].type = GRPC_ARG_INTEGER; + arg_array[1].key = + const_cast(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); + arg_array[1].value.integer = 1000; client_args.args = arg_array; - client_args.num_args = 1; + client_args.num_args = 2; /* create a channel that picks first amongst the servers */ grpc_channel* chan = From ad38c6eddf4f74398d6a025a819d4d28df2b4490 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 17 Jul 2019 11:03:22 -0700 Subject: [PATCH 653/676] Fix clang-tidy error. --- src/core/ext/filters/client_channel/subchannel.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index c3521f46cee..5e6cbccd93f 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -140,8 +140,9 @@ RefCountedPtr SubchannelCall::Create(Args args, const size_t allocation_size = args.connected_subchannel->GetInitialCallSizeEstimate( args.parent_data_size); - return RefCountedPtr(new (args.arena->Alloc( - allocation_size)) SubchannelCall(std::move(args), error)); + Arena* arena = args.arena; + return RefCountedPtr(new ( + arena->Alloc(allocation_size)) SubchannelCall(std::move(args), error)); } SubchannelCall::SubchannelCall(Args args, grpc_error** error) From b8a0271843476dd9e3d8f12550b0fec0cd34c70a Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Wed, 17 Jul 2019 14:00:51 -0700 Subject: [PATCH 654/676] Removed unused references to connectivityChange(d) --- src/objective-c/GRPCClient/GRPCCall.m | 19 ------------------- .../GRPCClient/private/GRPCChannelPool.m | 4 ---- 2 files changed, 23 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index a9b112b5d52..cd293cc8e59 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -892,23 +892,4 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } -- (void)connectivityChanged:(NSNotification *)note { - // Cancel underlying call upon this notification. - - // Retain because connectivity manager only keeps weak reference to GRPCCall. - __strong GRPCCall *strongSelf = self; - if (strongSelf) { - @synchronized(strongSelf) { - [_wrappedCall cancel]; - [strongSelf - finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeUnavailable - userInfo:@{ - NSLocalizedDescriptionKey : @"Connectivity lost." - }]]; - } - strongSelf->_requestWriter.state = GRXWriterStateFinished; - } -} - @end diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 683e203ca31..b6fafd3012f 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -260,10 +260,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } } -- (void)connectivityChange:(NSNotification *)note { - [self disconnectAllChannels]; -} - @end @implementation GRPCChannelPool (Test) From 9e675ecb901753a04fb9c0fde19e629b359df4db Mon Sep 17 00:00:00 2001 From: Tony Lu Date: Wed, 17 Jul 2019 14:07:09 -0700 Subject: [PATCH 655/676] Fixing clang_format_code failure --- src/objective-c/GRPCClient/private/GRPCChannelPool.m | 1 - 1 file changed, 1 deletion(-) diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index b6fafd3012f..d545793fcce 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -219,7 +219,6 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - } - (GRPCPooledChannel *)channelWithHost:(NSString *)host callOptions:(GRPCCallOptions *)callOptions { From 3776916fe96e43b0bd3f951d9ed9994ee3040575 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 17 Jul 2019 14:07:17 -0700 Subject: [PATCH 656/676] Modify shutdown check --- src/core/lib/iomgr/executor/threadpool.cc | 6 +++--- src/core/lib/iomgr/executor/threadpool.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index f0df1bd18eb..29eb0a67cf8 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -72,9 +72,9 @@ size_t ThreadPool::DefaultStackSize() { #endif } -bool ThreadPool::HasBeenShutDown() { +void ThreadPool::AssertHasBeenShutDown() { // For debug checking purpose, using RELAXED order is sufficient. - return shut_down_.Load(MemoryOrder::RELAXED); + GPR_DEBUG_ASSERT(!shut_down_.Load(MemoryOrder::RELAXED)); } ThreadPool::ThreadPool(int num_threads) : num_threads_(num_threads) { @@ -122,7 +122,7 @@ ThreadPool::~ThreadPool() { } void ThreadPool::Add(grpc_experimental_completion_queue_functor* closure) { - GPR_DEBUG_ASSERT(!HasBeenShutDown()); + AssertHasBeenShutDown(); queue_->Put(static_cast(closure)); } diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index 78f61a3139c..16277838fb0 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -145,7 +145,7 @@ class ThreadPool : public ThreadPoolInterface { // platforms is 64K. size_t DefaultStackSize(); // Internal Use Only for debug checking. - bool HasBeenShutDown(); + void AssertHasBeenShutDown(); }; } // namespace grpc_core From b7ee64c042ab088444c58d74dfd30e5781a89f1b Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Wed, 17 Jul 2019 13:02:00 -0700 Subject: [PATCH 657/676] Disable _FORTIFY_SOURCE when GPR_BACKWARDS_COMPATIBILITY_MODE --- include/grpc/impl/codegen/port_platform.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index d7294d59d41..446ab04868d 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -394,6 +394,17 @@ #endif #endif /* GPR_NO_AUTODETECT_PLATFORM */ +#if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) +/* + * For backward compatibility mode, reset _FORTIFY_SOURCE to prevent + * a library from having non-standard symbols such as __asprintf_chk. + * This helps non-glibc systems such as alpine using musl to find symbols. + */ +#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 +#define _FORTIFY_SOURCE 0 +#endif +#endif + /* * There are platforms for which TLS should not be used even though the * compiler makes it seem like it's supported (Android NDK < r12b for example). From c6993a3841a4802ad177966bd4f5b01c4922f9c9 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 16 Jul 2019 16:04:24 -0700 Subject: [PATCH 658/676] Run cfstream_test under ASAN and TSAN --- tools/bazel.rc | 3 +++ .../internal_ci/macos/grpc_cfstream_asan.cfg | 23 +++++++++++++++++++ .../internal_ci/macos/grpc_cfstream_tsan.cfg | 23 +++++++++++++++++++ .../internal_ci/macos/grpc_run_bazel_tests.sh | 2 +- 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tools/internal_ci/macos/grpc_cfstream_asan.cfg create mode 100644 tools/internal_ci/macos/grpc_cfstream_tsan.cfg diff --git a/tools/bazel.rc b/tools/bazel.rc index 7a716e85088..411457a7cf5 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -13,6 +13,9 @@ build:opt --copt=-Wframe-larger-than=16384 build:dbg --compilation_mode=dbg build:asan --strip=never +# Workaround for https://github.com/bazelbuild/bazel/issues/6932 +build:asan --copt -Wno-macro-redefined +build:asan --copt -D_FORTIFY_SOURCE=0 build:asan --copt=-fsanitize=address build:asan --copt=-O0 build:asan --copt=-fno-omit-frame-pointer diff --git a/tools/internal_ci/macos/grpc_cfstream_asan.cfg b/tools/internal_ci/macos/grpc_cfstream_asan.cfg new file mode 100644 index 00000000000..ceff78a4399 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream_asan.cfg @@ -0,0 +1,23 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--config=asan" +} + diff --git a/tools/internal_ci/macos/grpc_cfstream_tsan.cfg b/tools/internal_ci/macos/grpc_cfstream_tsan.cfg new file mode 100644 index 00000000000..52f1f3eec76 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream_tsan.cfg @@ -0,0 +1,23 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--config=tsan" +} + diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh index 56fae8fd75f..c64dcc5c95d 100644 --- a/tools/internal_ci/macos/grpc_run_bazel_tests.sh +++ b/tools/internal_ci/macos/grpc_run_bazel_tests.sh @@ -29,7 +29,7 @@ which bazel ./tools/run_tests/start_port_server.py # run cfstream_test separately because it messes with the network -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test +bazel test $RUN_TESTS_FLAGS --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test # kill port_server.py to prevent the build from hanging ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 From 09b62fbf3790347114b4ba6e1358af10989fc45a Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Wed, 17 Jul 2019 15:15:44 -0700 Subject: [PATCH 659/676] Fix naming --- src/core/lib/iomgr/executor/threadpool.cc | 4 ++-- src/core/lib/iomgr/executor/threadpool.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/executor/threadpool.cc b/src/core/lib/iomgr/executor/threadpool.cc index 29eb0a67cf8..e203252ef08 100644 --- a/src/core/lib/iomgr/executor/threadpool.cc +++ b/src/core/lib/iomgr/executor/threadpool.cc @@ -72,7 +72,7 @@ size_t ThreadPool::DefaultStackSize() { #endif } -void ThreadPool::AssertHasBeenShutDown() { +void ThreadPool::AssertHasNotBeenShutDown() { // For debug checking purpose, using RELAXED order is sufficient. GPR_DEBUG_ASSERT(!shut_down_.Load(MemoryOrder::RELAXED)); } @@ -122,7 +122,7 @@ ThreadPool::~ThreadPool() { } void ThreadPool::Add(grpc_experimental_completion_queue_functor* closure) { - AssertHasBeenShutDown(); + AssertHasNotBeenShutDown(); queue_->Put(static_cast(closure)); } diff --git a/src/core/lib/iomgr/executor/threadpool.h b/src/core/lib/iomgr/executor/threadpool.h index 16277838fb0..7b33fb32f36 100644 --- a/src/core/lib/iomgr/executor/threadpool.h +++ b/src/core/lib/iomgr/executor/threadpool.h @@ -145,7 +145,7 @@ class ThreadPool : public ThreadPoolInterface { // platforms is 64K. size_t DefaultStackSize(); // Internal Use Only for debug checking. - void AssertHasBeenShutDown(); + void AssertHasNotBeenShutDown(); }; } // namespace grpc_core From 8cc5b8f680ed4857e0734b9a951ada1ca25bf069 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 17 Jul 2019 13:14:43 -0700 Subject: [PATCH 660/676] Defer grpc shutdown until after channel destruction. --- src/core/lib/surface/channel.cc | 19 +++++++++++++++++++ test/cpp/microbenchmarks/bm_call_create.cc | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index e61550743b7..db7272dba6d 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -235,6 +235,23 @@ grpc_channel* grpc_channel_create(const char* target, grpc_channel_stack_type channel_stack_type, grpc_transport* optional_transport, grpc_resource_user* resource_user) { + // We need to make sure that grpc_shutdown() does not shut things down + // until after the channel is destroyed. However, the channel may not + // actually be destroyed by the time grpc_channel_destroy() returns, + // since there may be other existing refs to the channel. If those + // refs are held by things that are visible to the wrapped language + // (such as outstanding calls on the channel), then the wrapped + // language can be responsible for making sure that grpc_shutdown() + // does not run until after those refs are released. However, the + // channel may also have refs to itself held internally for various + // things that need to be cleaned up at channel destruction (e.g., + // LB policies, subchannels, etc), and because these refs are not + // visible to the wrapped language, it cannot be responsible for + // deferring grpc_shutdown() until after they are released. To + // accommodate that, we call grpc_init() here and then call + // grpc_shutdown() when the channel is actually destroyed, thus + // ensuring that shutdown is deferred until that point. + grpc_init(); grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); const grpc_core::UniquePtr default_authority = get_default_authority(input_args); @@ -468,6 +485,8 @@ static void destroy_channel(void* arg, grpc_error* error) { gpr_mu_destroy(&channel->registered_call_mu); gpr_free(channel->target); gpr_free(channel); + // See comment in grpc_channel_create() for why we do this. + grpc_shutdown(); } void grpc_channel_destroy(grpc_channel* channel) { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 3bd1464b2aa..aad94afca5b 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -686,6 +686,12 @@ static const grpc_channel_filter isolated_call_filter = { class IsolatedCallFixture : public TrackCounters { public: IsolatedCallFixture() { + // We are calling grpc_channel_stack_builder_create() instead of + // grpc_channel_create() here, which means we're not getting the + // grpc_init() called by grpc_channel_create(), but we are getting + // the grpc_shutdown() run by grpc_channel_destroy(). So we need to + // call grpc_init() manually here to balance things out. + grpc_init(); grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); grpc_channel_stack_builder_set_name(builder, "dummy"); grpc_channel_stack_builder_set_target(builder, "dummy_target"); From 38366dfec4a43d11593ae373086246cb129ad209 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 18 Jul 2019 10:39:11 +0200 Subject: [PATCH 661/676] fix nits --- doc/versioning.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/versioning.md b/doc/versioning.md index e39334d1df1..11f4c70963d 100644 --- a/doc/versioning.md +++ b/doc/versioning.md @@ -8,7 +8,7 @@ All gRPC implementations use a three-part version number (`vX.Y.Z`) and strictly - **Patch version bump** corresponds to bugfixes done on release branch. There are also a few extra rules regarding adding new gRPC implementations (e.g. adding support for a new language) -- New implementations start at v0.x.y version they reaches 1.0, they are considered not ready for production workloads. Breaking API changes are allowed in the 0.x releases as the library is not considered stable yet. +- New implementations start at v0.x.y version and until they reach 1.0, they are considered not ready for production workloads. Breaking API changes are allowed in the 0.x releases as the library is not considered stable yet. - The "1.0" release has semantics of GA (generally available) and being production ready. Requirements to reach this milestone are at least these - basic RPC features are feature complete and tested - implementation is tested for interoperability with other languages @@ -24,7 +24,7 @@ To avoid user confusion and simplify reasoning, the gRPC releases in different l - **voluntary change:** Even in non-forced situations, there might be circumstances in which a breaking API change makes sense and represents a net win, but as a rule of thumb breaking changes are very disruptive for users, cause user fragmentation and incur high maintenance costs. Therefore, breaking API changes should be very rare events that need to be considered with extreme care and the bar for accepting such changes is intentionally set very high. Example scenarios where a breaking API change might be adequate: - fixing a security problem which requires changes to API (need to consider the non-breaking alternatives first) - - the change leads to very significant gains to security, usability or development. velocity. These gains need to be clearly documented and claims need to be supported by evidence (ideally by numbers). Costs to the ecosystem (impact on users, dev team etc.) need to be taken into account and the change still needs to be a net positive after subtracting the costs. + - the change leads to very significant gains to security, usability or development velocity. These gains need to be clearly documented and claims need to be supported by evidence (ideally by numbers). Costs to the ecosystem (impact on users, dev team etc.) need to be taken into account and the change still needs to be a net positive after subtracting the costs. All proposals to make a breaking change need to be documented as a gRFC document (in the grpc/proposal repository) that covers at least these areas: - Description of the proposal including an explanation why the proposed change is one of the very rare events where a breaking change is introduced. From 5625006c00e49dbdc15e94ffce73f5b2169a17cd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 18 Jul 2019 10:42:43 +0200 Subject: [PATCH 662/676] regenerate doxygen --- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index bdb36ae1a7b..e85ae495546 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -794,6 +794,7 @@ doc/ssl-performance.md \ doc/status_ordering.md \ doc/statuscodes.md \ doc/unit_testing.md \ +doc/versioning.md \ doc/wait-for-ready.md \ doc/workarounds.md \ include/grpc++/alarm.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e711b662eae..626887290be 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -794,6 +794,7 @@ doc/ssl-performance.md \ doc/status_ordering.md \ doc/statuscodes.md \ doc/unit_testing.md \ +doc/versioning.md \ doc/wait-for-ready.md \ doc/workarounds.md \ include/grpc++/alarm.h \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 7235c7b1539..2836412b031 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -801,6 +801,7 @@ doc/ssl-performance.md \ doc/status_ordering.md \ doc/statuscodes.md \ doc/unit_testing.md \ +doc/versioning.md \ doc/wait-for-ready.md \ doc/workarounds.md \ include/grpc/byte_buffer.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 273c56e0242..5ac8256ce4b 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -801,6 +801,7 @@ doc/ssl-performance.md \ doc/status_ordering.md \ doc/statuscodes.md \ doc/unit_testing.md \ +doc/versioning.md \ doc/wait-for-ready.md \ doc/workarounds.md \ include/grpc/byte_buffer.h \ From f5a3e32b9b1ec178de3d23aa6bf173aae9470eca Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Thu, 18 Jul 2019 09:46:42 -0700 Subject: [PATCH 663/676] Take the mu_call mutex before zombifying pending calls so that there is no race between publishing new rpcs during a shutdown scenario --- src/core/lib/surface/server.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index a1c7d132ade..7fe05c10a54 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -711,8 +711,10 @@ static void maybe_finish_shutdown(grpc_server* server) { return; } + gpr_mu_lock(&server->mu_call); kill_pending_work_locked( server, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown")); + gpr_mu_unlock(&server->mu_call); if (server->root_channel_data.next != &server->root_channel_data || server->listeners_destroyed < num_listeners(server)) { From 3cd20e3d350e767be4d9baef3b4236a50deaf455 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 18 Jul 2019 12:11:01 -0700 Subject: [PATCH 664/676] Fix log level in CFStream Downgraded some log level of some log sites from ERROR to DEBUG. --- src/core/lib/iomgr/cfstream_handle.cc | 2 +- src/core/lib/iomgr/lockfree_event.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 8d01386a8f9..ea28e620695 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -184,7 +184,7 @@ void CFStreamHandle::Ref(const char* file, int line, const char* reason) { void CFStreamHandle::Unref(const char* file, int line, const char* reason) { if (grpc_tcp_trace.enabled()) { gpr_atm val = gpr_atm_no_barrier_load(&refcount_.count); - gpr_log(GPR_ERROR, + gpr_log(GPR_DEBUG, "CFStream Handle unref %p : %s %" PRIdPTR " -> %" PRIdPTR, this, reason, val, val - 1); } diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc index f33485ee59d..c7082345fd2 100644 --- a/src/core/lib/iomgr/lockfree_event.cc +++ b/src/core/lib/iomgr/lockfree_event.cc @@ -95,7 +95,7 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) { * referencing it. */ gpr_atm curr = gpr_atm_acq_load(&state_); if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_ERROR, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this, + gpr_log(GPR_DEBUG, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this, (void*)curr, closure); } switch (curr) { @@ -161,7 +161,7 @@ bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) { while (true) { gpr_atm curr = gpr_atm_no_barrier_load(&state_); if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_ERROR, "LockfreeEvent::SetShutdown: %p curr=%p err=%s", + gpr_log(GPR_DEBUG, "LockfreeEvent::SetShutdown: %p curr=%p err=%s", &state_, (void*)curr, grpc_error_string(shutdown_err)); } switch (curr) { @@ -210,7 +210,7 @@ void LockfreeEvent::SetReady() { gpr_atm curr = gpr_atm_no_barrier_load(&state_); if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_ERROR, "LockfreeEvent::SetReady: %p curr=%p", &state_, + gpr_log(GPR_DEBUG, "LockfreeEvent::SetReady: %p curr=%p", &state_, (void*)curr); } From b47d22f7f2cfc664277d58b5e3d0657f094d20b5 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 18 Jul 2019 11:50:11 -0700 Subject: [PATCH 665/676] Mark assert failure path as unlikely in codegen. Also, change an assert to debug assert in callback cpp. --- include/grpcpp/impl/codegen/callback_common.h | 4 +++- include/grpcpp/impl/codegen/core_codegen_interface.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index a3c8c41246c..6170170b978 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -201,9 +201,11 @@ class CallbackWithSuccessTag void* ignored = ops_; // Allow a "false" return value from FinalizeResult to silence the // callback, just as it silences a CQ tag in the async cases +#ifndef NDEBUG auto* ops = ops_; +#endif bool do_callback = ops_->FinalizeResult(&ignored, &ok); - GPR_CODEGEN_ASSERT(ignored == ops); + GPR_CODEGEN_DEBUG_ASSERT(ignored == ops); if (do_callback) { CatchingCallback(func_, ok); diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 02b5033c51f..8a7ac0ad452 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -144,7 +144,7 @@ extern CoreCodegenInterface* g_core_codegen_interface; /// Codegen specific version of \a GPR_ASSERT. #define GPR_CODEGEN_ASSERT(x) \ do { \ - if (!(x)) { \ + if (GPR_UNLIKELY(!(x))) { \ grpc::g_core_codegen_interface->assert_fail(#x, __FILE__, __LINE__); \ } \ } while (0) From 63b4f3d8195fc4c6196bf2e3a4705ab2fa16d1e4 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 18 Jul 2019 13:00:24 -0700 Subject: [PATCH 666/676] Revert "Merge pull request #19673 from markdroth/channel_grpc_init" This reverts commit 4e219807161f3cfe581ca8f79f5ae060c2631a8f, reversing changes made to 62b8a783fa376d6bfe277d6e1877b31f89e16553. --- src/core/lib/surface/channel.cc | 19 ------------------- test/cpp/microbenchmarks/bm_call_create.cc | 6 ------ 2 files changed, 25 deletions(-) diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index db7272dba6d..e61550743b7 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -235,23 +235,6 @@ grpc_channel* grpc_channel_create(const char* target, grpc_channel_stack_type channel_stack_type, grpc_transport* optional_transport, grpc_resource_user* resource_user) { - // We need to make sure that grpc_shutdown() does not shut things down - // until after the channel is destroyed. However, the channel may not - // actually be destroyed by the time grpc_channel_destroy() returns, - // since there may be other existing refs to the channel. If those - // refs are held by things that are visible to the wrapped language - // (such as outstanding calls on the channel), then the wrapped - // language can be responsible for making sure that grpc_shutdown() - // does not run until after those refs are released. However, the - // channel may also have refs to itself held internally for various - // things that need to be cleaned up at channel destruction (e.g., - // LB policies, subchannels, etc), and because these refs are not - // visible to the wrapped language, it cannot be responsible for - // deferring grpc_shutdown() until after they are released. To - // accommodate that, we call grpc_init() here and then call - // grpc_shutdown() when the channel is actually destroyed, thus - // ensuring that shutdown is deferred until that point. - grpc_init(); grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); const grpc_core::UniquePtr default_authority = get_default_authority(input_args); @@ -485,8 +468,6 @@ static void destroy_channel(void* arg, grpc_error* error) { gpr_mu_destroy(&channel->registered_call_mu); gpr_free(channel->target); gpr_free(channel); - // See comment in grpc_channel_create() for why we do this. - grpc_shutdown(); } void grpc_channel_destroy(grpc_channel* channel) { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index aad94afca5b..3bd1464b2aa 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -686,12 +686,6 @@ static const grpc_channel_filter isolated_call_filter = { class IsolatedCallFixture : public TrackCounters { public: IsolatedCallFixture() { - // We are calling grpc_channel_stack_builder_create() instead of - // grpc_channel_create() here, which means we're not getting the - // grpc_init() called by grpc_channel_create(), but we are getting - // the grpc_shutdown() run by grpc_channel_destroy(). So we need to - // call grpc_init() manually here to balance things out. - grpc_init(); grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); grpc_channel_stack_builder_set_name(builder, "dummy"); grpc_channel_stack_builder_set_target(builder, "dummy_target"); From 553eff9cb08f091e80a759b44b1a9ac8385981f0 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 18 Jul 2019 14:03:19 -0700 Subject: [PATCH 667/676] Fix a test failure due to unused variable and formatting --- test/cpp/end2end/client_callback_end2end_test.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index ea94ac77726..a54158ac1d1 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -391,8 +391,7 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) { stub_->experimental_async()->Echo( &cli_ctx1, &request1, &response1, [this, &mu1, &mu2, &mu3, &cv, &done, &request1, &request2, &request3, - &response1, &response2, &response3, &cli_ctx1, &cli_ctx2, - &cli_ctx3](Status s1) { + &response1, &response2, &response3, &cli_ctx2, &cli_ctx3](Status s1) { std::lock_guard l1(mu1); EXPECT_TRUE(s1.ok()); EXPECT_EQ(request1.message(), response1.message()); From 126ef2f735c14d406e054efb2d35ce6a75209421 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 18 Jul 2019 16:24:30 -0700 Subject: [PATCH 668/676] Added #undef --- include/grpc/impl/codegen/port_platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 446ab04868d..c0ca9f43716 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -401,6 +401,7 @@ * This helps non-glibc systems such as alpine using musl to find symbols. */ #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 +#undef _FORTIFY_SOURCE #define _FORTIFY_SOURCE 0 #endif #endif From 5efa660b41ab05971901f3a7b19e3890ea1e8884 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 18 Jul 2019 17:01:45 -0700 Subject: [PATCH 669/676] Remove warning for old linux without secure_getenv --- src/core/lib/gpr/env_linux.cc | 31 ++++++++++--------------------- src/core/lib/gpr/env_posix.cc | 5 ----- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index 3a3aa541672..6a78dc14155 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -38,19 +38,20 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -static const char* gpr_getenv_silent(const char* name, char** dst) { - const char* insecure_func_used = nullptr; +char* gpr_getenv(const char* name) { char* result = nullptr; #if defined(GPR_BACKWARDS_COMPATIBILITY_MODE) typedef char* (*getenv_type)(const char*); - static getenv_type getenv_func = NULL; + static getenv_type getenv_func = nullptr; /* Check to see which getenv variant is supported (go from most * to least secure) */ - const char* names[] = {"secure_getenv", "__secure_getenv", "getenv"}; - for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) { - getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]); - if (getenv_func != NULL && strstr(names[i], "secure") == NULL) { - insecure_func_used = names[i]; + if (getenv_func == nullptr) { + const char* names[] = {"secure_getenv", "__secure_getenv", "getenv"}; + for (size_t i = 0; i < GPR_ARRAY_SIZE(names); i++) { + getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]); + if (getenv_func != nullptr) { + break; + } } } result = getenv_func(name); @@ -58,20 +59,8 @@ static const char* gpr_getenv_silent(const char* name, char** dst) { result = secure_getenv(name); #else result = getenv(name); - insecure_func_used = "getenv"; #endif - *dst = result == nullptr ? result : gpr_strdup(result); - return insecure_func_used; -} - -char* gpr_getenv(const char* name) { - char* result = nullptr; - const char* insecure_func_used = gpr_getenv_silent(name, &result); - if (insecure_func_used != nullptr) { - gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used", - insecure_func_used); - } - return result; + return result == nullptr ? result : gpr_strdup(result); } void gpr_setenv(const char* name, const char* value) { diff --git a/src/core/lib/gpr/env_posix.cc b/src/core/lib/gpr/env_posix.cc index 30ddc50f682..232095b4e22 100644 --- a/src/core/lib/gpr/env_posix.cc +++ b/src/core/lib/gpr/env_posix.cc @@ -29,11 +29,6 @@ #include #include "src/core/lib/gpr/string.h" -const char* gpr_getenv_silent(const char* name, char** dst) { - *dst = gpr_getenv(name); - return nullptr; -} - char* gpr_getenv(const char* name) { char* result = getenv(name); return result == nullptr ? result : gpr_strdup(result); From 029ee95f1ac3d66bb225e1c5aae92fabb50f1909 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 18 Jul 2019 22:37:50 -0700 Subject: [PATCH 670/676] Resolve a race when background poller outlives executor --- src/core/lib/iomgr/combiner.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 4fc4a9dccf4..9a6290f29a8 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -233,11 +233,11 @@ bool grpc_combiner_continue_exec_ctx() { // offload only if all the following conditions are true: // 1. the combiner is contended and has more than one closure to execute // 2. the current execution context needs to finish as soon as possible - // 3. the DEFAULT executor is threaded - // 4. the current thread is not a worker for any background poller + // 3. the current thread is not a worker for any background poller + // 4. the DEFAULT executor is threaded if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish() && - grpc_core::Executor::IsThreadedDefault() && - !grpc_iomgr_is_any_background_poller_thread()) { + !grpc_iomgr_is_any_background_poller_thread() && + grpc_core::Executor::IsThreadedDefault()) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on: schedule remaining work to be // picked up on the executor From c7673983ac5932aa954d4dd141a20cfc80e5b7d6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 18 Jul 2019 11:34:35 +0200 Subject: [PATCH 671/676] get rid of unused Version.csproj.include --- src/csharp/Grpc.Core/Version.csproj.include | 7 ------- src/csharp/build/dependencies.props | 2 +- templates/src/csharp/build/dependencies.props.template | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100755 src/csharp/Grpc.Core/Version.csproj.include diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include deleted file mode 100755 index e24afdad605..00000000000 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ /dev/null @@ -1,7 +0,0 @@ - - - - 1.19.1 - 3.8.0 - - diff --git a/src/csharp/build/dependencies.props b/src/csharp/build/dependencies.props index d9bf90ff007..a91b5e19414 100644 --- a/src/csharp/build/dependencies.props +++ b/src/csharp/build/dependencies.props @@ -2,6 +2,6 @@ 1.23.0-dev - 3.7.0 + 3.8.0 diff --git a/templates/src/csharp/build/dependencies.props.template b/templates/src/csharp/build/dependencies.props.template index 0ed9018a49e..88470df2898 100755 --- a/templates/src/csharp/build/dependencies.props.template +++ b/templates/src/csharp/build/dependencies.props.template @@ -4,6 +4,6 @@ ${settings.csharp_version} - 3.7.0 + 3.8.0 From 91d865fa54b1a1105d50948426f27c5ef30e9616 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 17 Jul 2019 17:20:27 -0700 Subject: [PATCH 672/676] Create new build config for ASAN on Mac OS Workaround ASAN build issues on Mac OS. Disable LSAN as it's not supported by the version of clang that ships with Mac OS. --- tools/bazel.rc | 24 ++++++++++++++++--- .../internal_ci/macos/grpc_cfstream_asan.cfg | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tools/bazel.rc b/tools/bazel.rc index 411457a7cf5..e2d49355d8f 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -13,9 +13,6 @@ build:opt --copt=-Wframe-larger-than=16384 build:dbg --compilation_mode=dbg build:asan --strip=never -# Workaround for https://github.com/bazelbuild/bazel/issues/6932 -build:asan --copt -Wno-macro-redefined -build:asan --copt -D_FORTIFY_SOURCE=0 build:asan --copt=-fsanitize=address build:asan --copt=-O0 build:asan --copt=-fno-omit-frame-pointer @@ -25,6 +22,27 @@ build:asan --linkopt=-fsanitize=address build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 +# We have a separate ASAN config for Mac OS to workaround a couple of bugs: +# 1. https://github.com/bazelbuild/bazel/issues/6932 +# _FORTIFY_SOURCE=1 is enabled by default on Mac OS, which breaks ASAN. +# We workaround it by setting _FORTIFY_SOURCE=0 and ignoring macro redefined +# warnings. +# 2. https://github.com/google/sanitizers/issues/1026 +# LSAN is not supported by the version of Clang that ships with Mac OS, so +# we disable it. +build:asan_macos --strip=never +build:asan_macos --copt=-fsanitize=address +build:asan_macos --copt -Wno-macro-redefined +build:asan_macos --copt -D_FORTIFY_SOURCE=0 +build:asan_macos --copt=-fsanitize=address +build:asan_macos --copt=-O0 +build:asan_macos --copt=-fno-omit-frame-pointer +build:asan_macos --copt=-DGPR_NO_DIRECT_SYSCALLS +build:asan_macos --copt=-DADDRESS_SANITIZER # used by absl +build:asan_macos --linkopt=-fsanitize=address +build:asan_macos --action_env=ASAN_OPTIONS=detect_leaks=0 + + build:msan --strip=never build:msan --copt=-fsanitize=memory build:msan --copt=-O0 diff --git a/tools/internal_ci/macos/grpc_cfstream_asan.cfg b/tools/internal_ci/macos/grpc_cfstream_asan.cfg index ceff78a4399..ac8a8b63ff6 100644 --- a/tools/internal_ci/macos/grpc_cfstream_asan.cfg +++ b/tools/internal_ci/macos/grpc_cfstream_asan.cfg @@ -18,6 +18,6 @@ build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" env_vars { key: "RUN_TESTS_FLAGS" - value: "--config=asan" + value: "--config=asan_macos" } From 8d10d576d08efd1f7b997fc58c48f8e7721e2197 Mon Sep 17 00:00:00 2001 From: Yunjia Wang Date: Fri, 19 Jul 2019 10:55:16 -0700 Subject: [PATCH 673/676] Change page_size to local variable --- src/core/lib/gprpp/thd_posix.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 99197cbbfa9..2c3ae34ed44 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -49,11 +49,10 @@ struct thd_arg { bool tracked; }; -// TODO(yunjiaw): move this to a function-level static, or remove the use of a -// non-constexpr initializer when possible -const size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); - size_t RoundUpToPageSize(size_t size) { + // TODO(yunjiaw): Change this variable (page_size) to a function-level static + // when possible + size_t page_size = static_cast(sysconf(_SC_PAGESIZE)); return (size + page_size - 1) & ~(page_size - 1); } From 6d984166bd00bccd729ebbb2ae01752195b63f98 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 19 Jul 2019 11:45:33 -0700 Subject: [PATCH 674/676] Porting Aaron Jacob's unit test that detecting the race --- test/cpp/end2end/generic_end2end_test.cc | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index c2807310aa4..d0571dc1a6f 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -92,6 +92,7 @@ class GenericEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), InsecureChannelCredentials()); + stub_ = grpc::testing::EchoTestService::NewStub(channel); generic_stub_.reset(new GenericStub(channel)); } @@ -177,6 +178,54 @@ class GenericEnd2endTest : public ::testing::Test { } } + // Return errors to up to one call that comes in on the supplied completion + // queue, until the CQ is being shut down (and therefore we can no longer + // enqueue further events). + void DriveCompletionQueue() { + enum class Event : uintptr_t { + kCallReceived, + kResponseSent, + }; + // Request the call, but only if the main thread hasn't beaten us to + // shutting down the CQ. + grpc::GenericServerContext server_context; + grpc::GenericServerAsyncReaderWriter reader_writer(&server_context); + + { + std::lock_guard lock(shutting_down_mu_); + if (!shutting_down_) { + generic_service_.RequestCall( + &server_context, &reader_writer, srv_cq_.get(), srv_cq_.get(), + reinterpret_cast(Event::kCallReceived)); + } + } + // Process events. + { + Event event; + bool ok; + while (srv_cq_->Next(reinterpret_cast(&event), &ok)) { + std::lock_guard lock(shutting_down_mu_); + if (shutting_down_) { + // The main thread has started shutting down. Simply continue to drain + // events. + continue; + } + + switch (event) { + case Event::kCallReceived: + reader_writer.Finish( + ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "go away"), + reinterpret_cast(Event::kResponseSent)); + break; + + case Event::kResponseSent: + // We are done. + break; + } + } + } + } + CompletionQueue cli_cq_; std::unique_ptr srv_cq_; std::unique_ptr stub_; @@ -185,6 +234,8 @@ class GenericEnd2endTest : public ::testing::Test { AsyncGenericService generic_service_; const grpc::string server_host_; std::ostringstream server_address_; + bool shutting_down_; + std::mutex shutting_down_mu_; }; TEST_F(GenericEnd2endTest, SimpleRpc) { @@ -330,6 +381,32 @@ TEST_F(GenericEnd2endTest, Deadline) { gpr_time_from_seconds(10, GPR_TIMESPAN))); } +TEST_F(GenericEnd2endTest, ShortDeadline) { + ResetStub(); + + ClientContext cli_ctx; + EchoRequest request; + EchoResponse response; + + { + std::lock_guard lock(shutting_down_mu_); + shutting_down_ = false; + } + std::thread driver([=] { DriveCompletionQueue(); }); + + request.set_message(""); + cli_ctx.set_deadline(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_micros(500, GPR_TIMESPAN))); + Status s = stub_->Echo(&cli_ctx, request, &response); + EXPECT_FALSE(s.ok()); + { + std::lock_guard lock(shutting_down_mu_); + shutting_down_ = true; + } + TearDown(); + driver.join(); +} + } // namespace } // namespace testing } // namespace grpc From f4b1182a100c81eca490a614ad56e32b068750db Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 19 Jul 2019 13:48:35 -0700 Subject: [PATCH 675/676] Addressed review comments --- test/cpp/end2end/generic_end2end_test.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index d0571dc1a6f..92654ff0de0 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -388,11 +388,8 @@ TEST_F(GenericEnd2endTest, ShortDeadline) { EchoRequest request; EchoResponse response; - { - std::lock_guard lock(shutting_down_mu_); - shutting_down_ = false; - } - std::thread driver([=] { DriveCompletionQueue(); }); + shutting_down_ = false; + std::thread driver([this] { DriveCompletionQueue(); }); request.set_message(""); cli_ctx.set_deadline(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), From da85cec0f2251f504227af90798c8b38258b4e00 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Fri, 19 Jul 2019 14:19:23 -0700 Subject: [PATCH 676/676] Add condition to avoid duplicate shutdown --- test/cpp/end2end/generic_end2end_test.cc | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 92654ff0de0..f9f68bbe023 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -62,6 +62,7 @@ class GenericEnd2endTest : public ::testing::Test { GenericEnd2endTest() : server_host_("localhost") {} void SetUp() override { + shut_down_ = false; int port = grpc_pick_unused_port_or_die(); server_address_ << server_host_ << ":" << port; // Setup server @@ -77,17 +78,21 @@ class GenericEnd2endTest : public ::testing::Test { server_ = builder.BuildAndStart(); } - void TearDown() override { - server_->Shutdown(); - void* ignored_tag; - bool ignored_ok; - cli_cq_.Shutdown(); - srv_cq_->Shutdown(); - while (cli_cq_.Next(&ignored_tag, &ignored_ok)) - ; - while (srv_cq_->Next(&ignored_tag, &ignored_ok)) - ; + void ShutDownServerAndCQs() { + if (!shut_down_) { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cli_cq_.Shutdown(); + srv_cq_->Shutdown(); + while (cli_cq_.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq_->Next(&ignored_tag, &ignored_ok)) + ; + shut_down_ = true; + } } + void TearDown() override { ShutDownServerAndCQs(); } void ResetStub() { std::shared_ptr channel = grpc::CreateChannel( @@ -235,6 +240,7 @@ class GenericEnd2endTest : public ::testing::Test { const grpc::string server_host_; std::ostringstream server_address_; bool shutting_down_; + bool shut_down_; std::mutex shutting_down_mu_; }; @@ -400,7 +406,7 @@ TEST_F(GenericEnd2endTest, ShortDeadline) { std::lock_guard lock(shutting_down_mu_); shutting_down_ = true; } - TearDown(); + ShutDownServerAndCQs(); driver.join(); }