Line data Source code
1 : #include "source/exe/process_wide.h" 2 : 3 : #include "envoy/network/dns_resolver.h" 4 : 5 : #include "source/common/common/assert.h" 6 : #include "source/common/event/libevent.h" 7 : #include "source/common/http/http2/nghttp2.h" 8 : #include "source/server/proto_descriptors.h" 9 : 10 : namespace Envoy { 11 : namespace { 12 : 13 : struct InitData { 14 : uint32_t count_ ABSL_GUARDED_BY(mutex_){}; 15 : absl::Mutex mutex_; 16 : }; 17 : 18 : // Static variable to count initialization pairs. For tests like 19 : // main_common_test, we need to count to avoid double initialization or 20 : // shutdown. 21 138 : InitData& processWideInitData() { MUTABLE_CONSTRUCT_ON_FIRST_USE(InitData); }; 22 : } // namespace 23 : 24 69 : ProcessWide::ProcessWide(bool validate_proto_descriptors) { 25 : // Note that the following lock has the dual use of making sure that initialization is complete 26 : // before a second caller can enter and leave this function. 27 69 : auto& init_data = processWideInitData(); 28 69 : absl::MutexLock lock(&init_data.mutex_); 29 : 30 69 : if (init_data.count_++ == 0) { 31 : // TODO(mattklein123): Audit the following as not all of these have to be re-initialized in the 32 : // edge case where something does init/destroy/init/destroy. 33 69 : Event::Libevent::Global::initialize(); 34 69 : #if defined(ENVOY_ENABLE_FULL_PROTOS) 35 69 : if (validate_proto_descriptors) { 36 69 : Envoy::Server::validateProtoDescriptors(); 37 69 : } 38 : #else 39 : UNREFERENCED_PARAMETER(validate_proto_descriptors); 40 : #endif 41 69 : Http::Http2::initializeNghttp2Logging(); 42 : 43 : // We do not initialize Google gRPC here -- we instead instantiate 44 : // Grpc::GoogleGrpcContext in MainCommon immediately after instantiating 45 : // ProcessWide. This is because ProcessWide is instantiated in the unit-test 46 : // flow in test/test_runner.h, and grpc_init() instantiates threads which 47 : // allocate memory asynchronous to running tests, making it hard to 48 : // accurately measure memory consumption, and making unit-test debugging 49 : // non-deterministic. See https://github.com/envoyproxy/envoy/issues/8282 50 : // for details. Of course we also need grpc_init called in unit-tests that 51 : // test Google gRPC, and the relevant classes must also instantiate 52 : // Grpc::GoogleGrpcContext, which allows for nested instantiation. 53 : // 54 : // It appears that grpc_init() started instantiating threads in grpc 1.22.1, 55 : // which was integrated in https://github.com/envoyproxy/envoy/pull/8196, 56 : // around the time the flakes in #8282 started being reported. 57 69 : } 58 69 : } 59 : 60 69 : ProcessWide::~ProcessWide() { 61 69 : auto& init_data = processWideInitData(); 62 69 : absl::MutexLock lock(&init_data.mutex_); 63 : 64 69 : ASSERT(init_data.count_ > 0); 65 69 : if (--init_data.count_ == 0) { 66 69 : Network::DnsResolverFactory::terminateFactories(); 67 69 : } 68 69 : } 69 : 70 : } // namespace Envoy