/proc/self/cwd/source/exe/process_wide.cc
Line | Count | Source |
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 | 252 | InitData& processWideInitData() { MUTABLE_CONSTRUCT_ON_FIRST_USE(InitData); }; |
22 | | } // namespace |
23 | | |
24 | 126 | 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 | 126 | auto& init_data = processWideInitData(); |
28 | 126 | absl::MutexLock lock(&init_data.mutex_); |
29 | | |
30 | 126 | 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 | 126 | Event::Libevent::Global::initialize(); |
34 | 126 | #if defined(ENVOY_ENABLE_FULL_PROTOS) |
35 | 126 | if (validate_proto_descriptors) { |
36 | 126 | Envoy::Server::validateProtoDescriptors(); |
37 | 126 | } |
38 | | #else |
39 | | UNREFERENCED_PARAMETER(validate_proto_descriptors); |
40 | | #endif |
41 | 126 | 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 | 126 | } |
58 | 126 | } |
59 | | |
60 | 126 | ProcessWide::~ProcessWide() { |
61 | 126 | auto& init_data = processWideInitData(); |
62 | 126 | absl::MutexLock lock(&init_data.mutex_); |
63 | | |
64 | 126 | ASSERT(init_data.count_ > 0); |
65 | 126 | if (--init_data.count_ == 0) { |
66 | 126 | Network::DnsResolverFactory::terminateFactories(); |
67 | 126 | } |
68 | 126 | } |
69 | | |
70 | | } // namespace Envoy |