Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb/issues/142. This local document is retained as an engineering spec/evidence record.
BUG-147 - Recursive shared-directory add performs a foreground full shared-file reload¶
Summary¶
Adding a recursive shared directory from the Shared Files tree can still drive a
foreground full shared-file reload. In the observed large-share profile, the UI
thread stayed busy in a directory walk after the MP_SHAREDIRSUB command added
a recursive share.
This is separate from the peer shared-list directory-index fix: the network directory-list path is covered, but this local add path still calls the general reload flow and re-enumerates every configured share root instead of scanning only the newly added subtree.
Evidence¶
The 2026-06-07 dump showed the main thread in this path:
CSharedDirsTreeCtrl::OnCommand(...)handlingMP_SHAREDIRSUBCSharedDirsTreeCtrl::EditSharedDirectories(...)CSharedFilesWnd::Reload(true)CSharedFileList::Reload()CSharedFileList::FindSharedFiles(false)CSharedFileList::AddFilesFromDirectory(...)PathHelpers::ForEachDirectoryEntry(...)
The observed state had thousands of shared directories and tens of thousands of
known shared files. Logs later reported 38892 known shared files and 1808
new files queued for hashing, so the work completed, but only after a
foreground full walk.
Why This Matters¶
Recursive add is a targeted operation: the user adds one subtree and expects the new files under that subtree to appear. Rewalking all other shared roots makes the operation scale with the whole library and can look like a hang on large, deep, or long-path-capable shared trees.
The current behavior also bypasses startup-cache benefits because
FindSharedFiles(false) intentionally disables startup-cache restoration for
the foreground reload path.
Representative Sites¶
srchybrid/SharedDirsTreeCtrl.cpphandlesMP_SHAREDIRSUBand callsEditSharedDirectories(...).srchybrid/SharedDirsTreeCtrl.cppadd handling callssharedfileswnd->Reload(true).srchybrid/SharedFileList.cppReload()callsFindSharedFiles(false).srchybrid/SharedFileList.cppFindSharedFiles(false)walks all configured shared roots and does not use the startup cache.
Candidate Fix Direction¶
- Add a narrow incremental shared-file scan for newly added directory subtrees,
for example
CSharedFileList::ReloadSharedDirectorySubtree(...). - Reuse existing path canonicalization, long-path helpers, Unicode-safe filesystem enumeration, duplicate detection, hashing queue insertion, and UI refresh code instead of creating a parallel scanner.
- In the
MP_SHAREDIRSUBadd path, update preferences/shared-directory state, then scan only the newly added subtree and coalesce the shared-files UI refresh. - Keep removal and mode-change cases on the existing full reload path until there is a separate, proven invalidation design for subtractive changes.
- Add a source-level regression guard showing the recursive add path no longer calls the full shared-files reload.
Acceptance Criteria¶
- [ ] Adding a new recursive shared directory scans only the added subtree.
- [ ] Existing shared roots are not re-enumerated for the add-only path.
- [ ] Long paths and Unicode paths continue to use the existing project path helpers and supported filesystem APIs.
- [ ] Duplicate shared files, known-file reuse, hash queue insertion, and shared tree UI state match stock behavior after the incremental add.
- [ ] Removing a shared directory or changing recursive/share mode still uses the existing full reload path unless separately redesigned.
- [ ] The local large shared-tree swarm/regression test covers this command path with a bucketed fake shared tree.
- [ ] Debug and Release x64 app builds pass before implementation commit.