Line data Source code
1 : #include "source/common/grpc/google_grpc_context.h" 2 : 3 : #include <atomic> 4 : 5 : #include "source/common/common/assert.h" 6 : #include "source/common/common/lock_guard.h" 7 : #include "source/common/common/macros.h" 8 : #include "source/common/common/thread.h" 9 : 10 : #ifdef ENVOY_GOOGLE_GRPC 11 : #include "grpcpp/grpcpp.h" 12 : #endif 13 : 14 : namespace Envoy { 15 : namespace Grpc { 16 : 17 226 : GoogleGrpcContext::GoogleGrpcContext() : instance_tracker_(instanceTracker()) { 18 226 : #ifdef ENVOY_GOOGLE_GRPC 19 226 : Thread::LockGuard lock(instance_tracker_.mutex_); 20 226 : if (++instance_tracker_.live_instances_ == 1) { 21 131 : grpc_init(); 22 131 : } 23 226 : #endif 24 226 : } 25 : 26 226 : GoogleGrpcContext::~GoogleGrpcContext() { 27 226 : #ifdef ENVOY_GOOGLE_GRPC 28 : // Per https://github.com/grpc/grpc/issues/20303 it is OK to call 29 : // grpc_shutdown_blocking() as long as no one can concurrently call 30 : // grpc_init(). We use check_format.py to ensure that this file contains the 31 : // only callers to grpc_init(), and the mutex to then make that guarantee 32 : // across users of this class. 33 226 : Thread::LockGuard lock(instance_tracker_.mutex_); 34 226 : ASSERT(instance_tracker_.live_instances_ > 0); 35 226 : if (--instance_tracker_.live_instances_ == 0) { 36 131 : grpc_shutdown_blocking(); // Waiting for quiescence avoids non-determinism in tests. 37 131 : } 38 226 : #endif 39 226 : } 40 : 41 226 : GoogleGrpcContext::InstanceTracker& GoogleGrpcContext::instanceTracker() { 42 226 : MUTABLE_CONSTRUCT_ON_FIRST_USE(InstanceTracker); 43 226 : } 44 : 45 : } // namespace Grpc 46 : } // namespace Envoy