BUG: Remove unnecessary global fflush(nullptr) causing MetaIO read deadlocks - #146
Merged
Merged
Conversation
…adlocks MetaObject::ReadStream() and MetaForm::ReadStream() unconditionally call fflush(nullptr) before parsing, a leftover from the original MetaIO commit that predates any multithreading concerns for this library. fflush(NULL) flushes every open FILE* stream in the entire process, not just the one being read. On platforms such as macOS, this requires walking the process-wide list of all open FILE* streams and locking each one in turn. Under heavy concurrent MetaImage/MHA reads (many threads each opening/reading/closing their own files), this global flush-all creates severe lock contention that can grind concurrent reads to a halt indefinitely, since each thread's fflush(nullptr) call competes to lock every other thread's in-flight FILE* handle. Reading does not require flushing any previously written data, so this call serves no purpose and can simply be removed. Ported from InsightSoftwareConsortium/ITK#6833. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
dzenanz
approved these changes
Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MetaObject::ReadStream() and MetaForm::ReadStream() unconditionally call fflush(nullptr) before parsing header fields. This line dates back to MetaIO's very first file-IO commit, long before multithreading was a design concern for this library.
fflush(NULL) flushes every open FILE* stream in the entire process, not just the one being read. On platforms such as macOS, this requires walking the process-wide list of all open FILE* streams and locking each one in turn (_fwalk -> sflush_locked -> flockfile).
Under heavy concurrent MetaImage/.mha reads (many threads, each opening/reading/closing its own file), this global flush-all creates severe lock contention: every thread's fflush(nullptr) call competes to lock every other thread's in-flight FILE* handle. In practice this can grind concurrent reads to a halt indefinitely.
Reading a file does not require flushing any previously written data (nothing was just written), so this call serves no purpose and can simply be removed.
Ported from InsightSoftwareConsortium/ITK#6833.
Test plan
-DBUILD_TESTING=ONninjabuild succeeds cleanlyctest— all 14 tests pass, including testMeta2Object, testMeta3Image, and testMeta11Form which exercise the ReadStream() code paths touched by this change