Skip to content

Close the .xsb output when a save is abandoned part-way through - #112

Merged
pjfanning merged 1 commit into
apache:trunkfrom
pjfanning:leak-xsb-save-path
Sep 7, 2026
Merged

Close the .xsb output when a save is abandoned part-way through#112
pjfanning merged 1 commit into
apache:trunkfrom
pjfanning:leak-xsb-save-path

Conversation

@pjfanning

Copy link
Copy Markdown
Member

Every saveXxx() in SchemaTypeSystemImpl (saveIndex, savePointerFile, saveGlobalElement, saveGlobalAttribute, saveModelGroup, saveAttributeGroup, saveIdentityConstraint, saveType) runs the same sequence:

XsbReader saver = new XsbReader(getTypeSystem(), handle);
saver.writeTypeData(type);                            // fills the string pool
saver.writeRealHeader(handle, FILETYPE_SCHEMATYPE);   // opens the Filer output stream
saver.writeTypeData(type);                            // the real write
saver.writeEnd();                                     // flush + close

Nothing guards the middle. Every write helper raises SchemaTypeLoaderException on an IOException, so a failing write skips writeEnd() and leaves the .xsb output stream open over a partial file. scomp writes one file per global type, so a failure part-way through a large schema leaks a descriptor for each one already opened.

Adds XsbReader.closeOutputQuietly() — a no-op once writeEnd() has cleared _output — and calls it from a finally in all eight save methods. Closing quietly rather than calling writeEnd() keeps the original failure from being masked by a second SchemaTypeLoaderException.

Added XsbSaveStreamTest, which serves a Filer output stream that opens and then fails every write, and asserts the stream is closed. It fails on trunk and passes with this change. compile.scomp.checkin.CompilationTests still passes.

🤖 Generated with Claude Code

Every saveXxx() in SchemaTypeSystemImpl runs the same sequence: construct an
XsbReader, write the component once to fill the string pool, call
writeRealHeader() - which opens a Filer output stream - write it again, then
writeEnd() to flush and close.

Nothing guards the middle. If any write throws, and they all raise
SchemaTypeLoaderException on an IO error, writeEnd() is skipped and the .xsb
output stream is left open with a partial file behind it. With scomp writing
one file per global type, a failure part-way through a large schema leaks a
descriptor for each of them.

Add XsbReader.closeOutputQuietly(), which releases a stream a completed
writeEnd() has already cleared, and call it from a finally in all eight save
methods. Closing quietly keeps the original failure from being masked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@pjfanning
pjfanning merged commit c863d21 into apache:trunk Sep 7, 2026
3 checks passed
@pjfanning
pjfanning deleted the leak-xsb-save-path branch September 7, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant