[Fix] (Pipe): re-parse the POISON_OMIT and VERIFY knobs when their Features value changes, not once per process

- The two parsers (ParsePoisonOmissionKnob, ArmVerify) latched on the first fill, so the only way to reach them was a lane that loads MG_Config::Features before any fill; no unit test could exercise the parse, the arming lines or Fatal{PipeVerifyBadKnob}.
- The latch now keys on the value: a lane still parses once (Features is loaded before the first fill), while a forked test child that sets Features after its parent filled gets its own parse. An empty omission value never clears an omission armed through MGPipeSetPoisonOmission.
- Re-arming resets the CORRUPT field so a stale corruption cannot outlive the knob that named it.
This commit is contained in:
2026-09-06 02:31:56 -04:00
parent 77ecde1524
commit 878db2c405
+14 -3
View File
@@ -296,11 +296,18 @@ namespace MobileGL::MG_Pipe {
};
PoisonOmission g_omission;
Bool g_omissionKnobParsed = false;
String g_omissionKnobValue; // the value the last parse saw
// Parsed on the first fill and again only when the value changes. A lane loads
// Features once, before any fill, so that is one parse per process there; a forked
// test child that sets Features after its parent already filled gets its own parse,
// which is what puts the parser and its Fatal{PipeVerifyBadKnob} under a unit test.
// An empty value never clears an omission a test armed through MGPipeSetPoisonOmission.
void ParsePoisonOmissionKnob() {
if (g_omissionKnobParsed) return;
g_omissionKnobParsed = true;
const String& knob = MG_Config::Features.PipePoisonOmit;
if (g_omissionKnobParsed && knob == g_omissionKnobValue) return;
g_omissionKnobParsed = true;
g_omissionKnobValue = knob;
if (knob.empty()) return;
const auto colon = knob.find(':');
if (colon == String::npos || colon == 0 || colon + 1 >= knob.size()) {
@@ -348,10 +355,14 @@ namespace MobileGL::MG_Pipe {
};
VerifyState g_verify;
// Armed on the first fill and re-armed only when Features.PipeVerify changes (the
// same reason as ParsePoisonOmissionKnob: one arm per lane process, a fresh arm for a
// forked test child that turns the knob on after its parent filled unarmed).
void ArmVerify() {
if (g_verify.Parsed) return;
if (g_verify.Parsed && g_verify.Enabled == MG_Config::Features.PipeVerify) return;
g_verify.Parsed = true;
g_verify.Enabled = MG_Config::Features.PipeVerify;
g_verify.Corrupt = Optional<MGPipeInputField>{};
if (!g_verify.Enabled) return;
g_verify.Fatal = MG_Config::Features.PipeVerifyFatal;
const String& corrupt = MG_Config::Features.PipeVerifyCorrupt;