Fix iterator cleanup and configuration guidance

This commit is contained in:
2026-08-24 22:36:39 +10:00
parent 05b7bef920
commit 5c6d0140c5
15 changed files with 124 additions and 68 deletions
+12
View File
@@ -12,7 +12,19 @@ DeviceFrameworkTemplateContext::DeviceFrameworkTemplateContext()
}
}
DeviceFrameworkTemplateContext::~DeviceFrameworkTemplateContext() {
while (renderingDepth > 0) {
popContext();
}
}
void DeviceFrameworkTemplateContext::reset() {
// An interrupted render may own an iterator handle. Pop through the stack
// before overwriting it so every descriptor receives its close callback.
while (renderingDepth > 0) {
popContext();
}
state = TemplateRenderState::TEXT;
renderingDepth = 0;
placeholderPos = 0;
+13
View File
@@ -354,6 +354,9 @@ DeviceFrameworkTemplateRenderer::RenderOutcome DeviceFrameworkTemplateRenderer::
if (!applyStackCommands(ctx, outcome)) {
ctx.state = TemplateRenderState::ERROR;
while (ctx.renderingDepth > 0) {
ctx.popContext();
}
return makeError();
}
@@ -369,6 +372,13 @@ DeviceFrameworkTemplateRenderer::RenderOutcome DeviceFrameworkTemplateRenderer::
outcome.finished = (ctx.state == TemplateRenderState::COMPLETE);
outcome.errored = (ctx.state == TemplateRenderState::ERROR);
if (outcome.errored) {
// Error paths can leave a live iterator below the active context.
// Pop all contexts so its close handler is called exactly once.
while (ctx.renderingDepth > 0) {
ctx.popContext();
}
}
return outcome;
}
@@ -875,6 +885,9 @@ size_t DeviceFrameworkTemplateRenderer::renderNextChunk(DeviceFrameworkTemplateC
DFTE_LOG_WARN("Maximum iterations reached in renderNextChunk");
if (consecutiveNoProgressIterations >= 3 && !ctx.isComplete() && !ctx.hasError()) {
ctx.state = TemplateRenderState::ERROR;
while (ctx.renderingDepth > 0) {
ctx.popContext();
}
}
}