AICH sync thread concurrency — multiple unsynchronized shared-state accesses
Historical reference only:
stale-v0.72a-experimental-cleanandanalysis\stale-v0.72a-experimental-cleanare retired reference sources, not active branch targets or current baselines. Use them only as provenance or idea-extraction sources; landed status is determined againstmain. See Historical References.
Summary¶
The AICH sync thread (CAICHSyncThread) accesses shared state with insufficient
synchronization in several dimensions:
1. UI deadlock + hash starvation (9770d3d)¶
CAICHSyncThread calls PostMessage and waits for completion from the main window while
holding locks that the UI thread may also try to acquire. Under load this produces a
deadlock cycle: hasher holds a file-list lock and waits for UI ack; UI processes other
messages that also need the file-list lock.
A related starvation path exists where the AICH maintenance loop runs at higher-than-expected frequency and starves download/upload threads of I/O time.
Files affected: srchybrid/AICHSyncThread.cpp, srchybrid/EmuleDlg.cpp,
srchybrid/DownloadClient.cpp, srchybrid/PartFile.cpp, srchybrid/UploadClient.cpp
(+228/-27 in experimental, 13 files)
2. AICH sync thread concurrency — bounded maintenance wait (c3d0a47)¶
CAICHSyncThread performs AICH tree maintenance operations without a bounded wait before
re-entering its main loop. The fix bounds the maintenance sleep, reduces lock hold time,
and ensures the sync state machine is consistent.
Files affected: srchybrid/AICHSyncThread.cpp (+156/-39 lines), srchybrid/AICHSyncThread.h
3. Incomplete/duplicate AICH tree nodes (ad705b0, 10fdc85)¶
AICH tree serialization/deserialization can encounter:
- Incomplete nodes (partial subtrees stored on crash/abort): ad705b0 normalize incomplete AICH tree nodes
- Duplicate stored hash entries: 10fdc85 tolerate duplicate stored AICH hashes (CPP_032/CPP_035)
These cause AICH verification failures on reload even when the underlying file data is correct.
Files affected: AICH hash-set storage and loading paths (kademlia + PartFile vicinity)
Location¶
srchybrid/AICHSyncThread.cpp/AICHSyncThread.hsrchybrid/PartFile.cppsrchybrid/EmuleDlg.cpp,srchybrid/DownloadClient.cpp,srchybrid/UploadClient.cpp- Seam headers in experimental:
AICHSyncThreadSeams.h,DisplayRefreshSeams.h
Experimental Reference Implementation¶
Status: All four aspects fixed in experimental:
- 9770d3d FIX: prevent runtime UI deadlocks and hash starvation (2026)
- c3d0a47 FIX: harden AICH sync thread concurrency (2026)
- ad705b0 BUG CPP_032 CPP_035 normalize incomplete AICH tree nodes (2026)
- 10fdc85 BUG CPP_032 CPP_035 tolerate duplicate stored AICH hashes (2026)
The approach for the UI deadlock: replace blocking PostMessage+wait with the
QueueDisplayUpdate / DISPLAY_REFRESH_* message pattern, allowing the AICH thread to
post updates without waiting for UI ack. The AICH maintenance loop now uses a bounded
interrupt-able sleep rather than WaitForSingleObject(INFINITE).
For duplicate/incomplete nodes: add skip-and-heal logic during tree load instead of hard failing; normalize subtrees to a known-valid empty state when partial data is detected.
Main Branch Port Status¶
Status: Done in main
The staged branch port was squash-merged to main as:
6e466d2BUG-019 harden AICH sync concurrency5d8346cBUG-019 add AICH sync hardening regressionsbfebdd2BUG-019 update AICH sync hardening tracking
Current branch behavior:
- Duplicate stored AICH hashes are tolerated during load instead of hard-failing the index.
- Incomplete tree nodes are normalized to a safe invalid state during repair/load.
- AICH maintenance waits are bounded and cooperative rather than effectively unbounded.
- AICH worker-thread display updates are routed through queued
QueueDisplayUpdate/DispatchQueuedDisplayUpdatehandoff instead of waiting on synchronous UI acknowledgment.
Current branch implementation notes:
- Shared-state and maintenance logic use the existing
AICHMaintenanceSeamsandAICHSyncThreadSeamsseam vocabulary already present onmain. - UI refresh routing now uses
DisplayRefreshSeams,UM_PARTFILE_DISPLAY_UPDATE, andUM_CLIENT_DISPLAY_UPDATEto queue part-file/client refresh work back to the main thread. - The queued display-refresh path touches
EmuleDlg,PartFile,DownloadClient,UploadClient,BaseClient,ListenSocket, andUploadQueue.
Regression coverage landed with the merge:
5d8346cBUG-019 add AICH sync hardening regressions
Porting Note¶
The stale experimental branch remains the reference source for the original fixes, but the main branch now carries the staged ported behavior: isolated storage/tree-healing, bounded sync waits, and queued display refresh handoff.
Relationship to Existing Items¶
- BUG-018 (part-file hash layout drift): BUG-018 covers the hasher thread; BUG-019 covers the AICH sync thread.
- BUG-003 (AICH FIXME markers): BUG-003 tracks incomplete large-file AICH paths via FIXME markers; BUG-019 tracks runtime concurrency issues in the existing paths.