[experiments] Fix initialization order fiasco (#36168)

Internal ref : b/324720620

Closes #36168

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36168 from yashykt:FixStaticOrderInitFiasco 14f2a89503
PiperOrigin-RevId: 618328195
pull/36170/head
Yash Tibrewal 1 year ago committed by Copybara-Service
parent 604a8b9155
commit 041c283ccc
  1. 33
      src/core/lib/experiments/config.cc
  2. 0
      test/core/end2end/end2end_test_corpus/retry_streaming/clusterfuzz-testcase-minimized-retry_streaming_fuzzer-6651400812036096

@ -49,9 +49,16 @@ struct ForcedExperiment {
bool forced = false;
bool value;
};
ForcedExperiment g_forced_experiments[kNumExperiments];
std::atomic<bool> g_loaded(false);
ForcedExperiment* ForcedExperiments() {
static NoDestruct<ForcedExperiment> forced_experiments[kNumExperiments];
return &**forced_experiments;
}
std::atomic<bool>* Loaded() {
static NoDestruct<std::atomic<bool>> loaded(false);
return &*loaded;
}
absl::AnyInvocable<bool(struct ExperimentMetadata)>* g_check_constraints_cb =
nullptr;
@ -98,7 +105,7 @@ GPR_ATTRIBUTE_NOINLINE Experiments LoadExperimentsFromConfigVariableInner() {
// Set defaults from metadata.
Experiments experiments;
for (size_t i = 0; i < kNumExperiments; i++) {
if (!g_forced_experiments[i].forced) {
if (!ForcedExperiments()[i].forced) {
if (g_check_constraints_cb != nullptr) {
experiments.enabled[i] =
(*g_check_constraints_cb)(g_experiment_metadata[i]);
@ -106,7 +113,7 @@ GPR_ATTRIBUTE_NOINLINE Experiments LoadExperimentsFromConfigVariableInner() {
experiments.enabled[i] = g_experiment_metadata[i].default_value;
}
} else {
experiments.enabled[i] = g_forced_experiments[i].value;
experiments.enabled[i] = ForcedExperiments()[i].value;
}
}
// For each comma-separated experiment in the global config:
@ -151,7 +158,7 @@ GPR_ATTRIBUTE_NOINLINE Experiments LoadExperimentsFromConfigVariableInner() {
}
Experiments LoadExperimentsFromConfigVariable() {
g_loaded.store(true, std::memory_order_relaxed);
Loaded()->store(true, std::memory_order_relaxed);
return LoadExperimentsFromConfigVariableInner();
}
@ -193,7 +200,7 @@ void PrintExperimentsList() {
const char* name = g_experiment_metadata[i].name;
const bool enabled = IsExperimentEnabled(i);
const bool default_enabled = g_experiment_metadata[i].default_value;
const bool forced = g_forced_experiments[i].forced;
const bool forced = ForcedExperiments()[i].forced;
if (!default_enabled && !enabled) continue;
if (default_enabled && enabled) {
defaulted_on_experiments.insert(name);
@ -205,13 +212,13 @@ void PrintExperimentsList() {
experiment_status[name] = "on:constraints";
continue;
}
if (forced && g_forced_experiments[i].value) {
if (forced && ForcedExperiments()[i].value) {
experiment_status[name] = "on:forced";
continue;
}
experiment_status[name] = "on";
} else {
if (forced && !g_forced_experiments[i].value) {
if (forced && !ForcedExperiments()[i].value) {
experiment_status[name] = "off:forced";
continue;
}
@ -238,14 +245,14 @@ void PrintExperimentsList() {
}
void ForceEnableExperiment(absl::string_view experiment, bool enable) {
GPR_ASSERT(g_loaded.load(std::memory_order_relaxed) == false);
GPR_ASSERT(Loaded()->load(std::memory_order_relaxed) == false);
for (size_t i = 0; i < kNumExperiments; i++) {
if (g_experiment_metadata[i].name != experiment) continue;
if (g_forced_experiments[i].forced) {
GPR_ASSERT(g_forced_experiments[i].value == enable);
if (ForcedExperiments()[i].forced) {
GPR_ASSERT(ForcedExperiments()[i].value == enable);
} else {
g_forced_experiments[i].forced = true;
g_forced_experiments[i].value = enable;
ForcedExperiments()[i].forced = true;
ForcedExperiments()[i].value = enable;
}
return;
}

Loading…
Cancel
Save