PartFile: first-share early hash so downloading files appear in "Shared files" - #762
Merged
mrjimenez merged 1 commit intoMay 28, 2026
Conversation
"Shared files" without waiting for quiescence SafeAddKFile fires only from OnAsyncHashComplete and only when status == PS_EMPTY, so it must run at least once for a fresh partfile to enter the shared list. FlushBuffer's Phase 3 enqueues to the async hash thread, but two gates added with the defer-hash work keep it shut during active download: 1. m_iWrites > 0 early-return: any queued write blocks Phase 3 2. 1 s quiescent window on m_nLastBlockReceivedTick A sustained download keeps both engaged across the whole transfer, so OnAsyncHashComplete never fires, SafeAddKFile never runs, and the file stays invisible until the user pauses, restarts, or it completes (amule-project#761). 2.3.3 (pre-async-hash) hashed synchronously when a part became complete and shared on the first success, which is the behavior danim7 noted as the regression. Add a first-share early path: when status == PS_EMPTY and the hashset is fully present, scan m_aChangedPart for one gap-complete part with no pending write overlap and enqueue it -- bypassing both gates. m_pendingHashes==0 in the gate keeps the path single-shot; status flips to PS_READY on the worker's first success, and the path is dormant for the rest of the session. On a corrupt first part the worker reports the failure, m_pendingHashes returns to 0, status stays PS_EMPTY, and the next FlushBuffer picks another candidate -- self-arming until something verifies. The per-part scan of m_BufferedData_list for non-PB_WRITTEN overlap matters because FillGap runs at queue time in WriteToBuffer, so IsComplete(N) can be true while a PB_PENDING/PB_READY write to N is still in the buffer; hashing then would read pre-write bytes and falsely mark the part corrupt. The destructor / shutdown gate was hoisted above the m_iWrites check so the new path inherits it.
1 task
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jun 4, 2026
…ndex Adds 55+ merged PRs to the 3.0.0 changelog since the last update (amule-project#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796 (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths). - Bug Fixes & Stability: post-amule-project#744 fixes including EC notification leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728), amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760), PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788, amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756), Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833, amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774). - Translations: late-cycle wave covering French/Turkish manpages (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for date+version drift (amule-project#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
got3nks
added a commit
to got3nks/amule
that referenced
this pull request
Jun 4, 2026
…ndex Adds 55+ merged PRs to the 3.0.0 changelog since the last update (amule-project#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796 (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths). - Bug Fixes & Stability: post-amule-project#744 fixes including EC notification leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728), amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760), PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788, amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756), Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833, amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774). - Translations: late-cycle wave covering French/Turkish manpages (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for date+version drift (amule-project#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
mrjimenez
pushed a commit
that referenced
this pull request
Jun 4, 2026
Adds 55+ merged PRs to the 3.0.0 changelog since the last update (#747, 2026-05-27). Narrative additions cover: - Packaging: expanded the top list to include the macOS per-arch .app bundles and the Windows NSIS installer alongside the existing AppImage / Flatpak / .dmg / .zip entries. New bullets for #785 (alc/alcc/cas/wxcas everywhere + Windows amuleweb), #794 (.dmg amuleweb path), #789 (<OS>-<arch> artifact naming), #780 / #796 (Windows DPI + comctl32 manifest), #784 (FHS share/amule paths). - Bug Fixes & Stability: post-#744 fixes including EC notification leak (#797), big-library scaling (#736, #840 superseding #728), amulegui ghost entries (#810, #819, #841, #824, #830, #760), PartFile early hash (#762), server protocol fixes (#835, #788, #721, #787), crypto stream UB (#779), UAF prevention (#756), Kad rotation (#795, #799/#805), GTK warning silencing (#833, #826/#836), and the clang-tidy worklist (#770, #772-#774). - Translations: late-cycle wave covering French/Turkish manpages (#753/#754/#776), Galician (#763), Slovenian (#771), pt-BR (#768/#775/#812), French (#811), plus man-page tooling for date+version drift (#802). - Contributors: added ngosang for UX feedback on the late-3.0 cycle (#817/#818/#821/#828/#844) and ongoing work on the user-facing manual at amule-org.github.io. - Merged PRs flat index: extended with #746-#845 + #841.
mrjimenez
pushed a commit
to mrjimenez/amule
that referenced
this pull request
Aug 4, 2026
Translated using Weblate (Tamil) Currently translated at 0.8% (2 of 246 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/ta/ Translated using Weblate Translated using Weblate (Tamil) Currently translated at 1.2% (24 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ta/ Translated using Weblate Translated using Weblate (Latvian) Currently translated at 60.9% (150 of 246 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/lv/ Translated using Weblate Translated using Weblate (Latvian) Currently translated at 32.4% (621 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/lv/ Translated using Weblate Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 86.8% (218 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/zh_Hant/ Translated using Weblate Translated using Weblate (Turkish) Currently translated at 98.0% (246 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/tr/ Translated using Weblate Translated using Weblate (Russian) Currently translated at 100.0% (251 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/ru/ Translated using Weblate Translated using Weblate (Russian) Currently translated at 100.0% (251 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/ru/ Translated using Weblate Translated using Weblate (Romanian) Currently translated at 86.8% (218 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/ro/ Translated using Weblate Translated using Weblate (Portuguese (Brazil)) Currently translated at 96.8% (243 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/pt_BR/ Translated using Weblate Translated using Weblate (Italian) Currently translated at 100.0% (251 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/it/ Translated using Weblate Translated using Weblate (Italian) Currently translated at 100.0% (251 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/it/ Translated using Weblate Translated using Weblate (Hungarian) Currently translated at 86.8% (218 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/hu/ Translated using Weblate Translated using Weblate (French) Currently translated at 98.0% (246 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/fr/ Translated using Weblate Translated using Weblate (Spanish) Currently translated at 98.0% (246 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/es/ Translated using Weblate Translated using Weblate (German) Currently translated at 96.4% (242 of 251 strings) Translation: aMule/Application Man Pages Translate-URL: https://hosted.weblate.org/projects/amule/application-man-pages/de/ Translated using Weblate Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 80.2% (1537 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/zh_Hant/ Translated using Weblate Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 99.4% (1905 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/zh_Hans/ Translated using Weblate Translated using Weblate (Ukrainian) Currently translated at 73.9% (1416 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/uk/ Translated using Weblate Translated using Weblate (Turkish) Currently translated at 95.7% (1835 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/tr/ Translated using Weblate Translated using Weblate (Swedish) Currently translated at 80.8% (1550 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/sv/ Translated using Weblate Translated using Weblate (Albanian) Currently translated at 60.1% (1153 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/sq/ Translated using Weblate Translated using Weblate (Slovenian) Currently translated at 81.1% (1554 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/sl/ Translated using Weblate Translated using Weblate (Russian) Currently translated at 80.3% (1539 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ru/ Translated using Weblate Translated using Weblate (Russian) Currently translated at 80.3% (1539 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ru/ Translated using Weblate Translated using Weblate (Romanian) Currently translated at 80.8% (1549 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ro/ Translated using Weblate Translated using Weblate (Portuguese (Portugal)) Currently translated at 80.0% (1534 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/pt_PT/ Translated using Weblate Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.4% (1905 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/pt_BR/ Translated using Weblate Translated using Weblate (Polish) Currently translated at 78.1% (1497 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/pl/ Translated using Weblate Translated using Weblate (Norwegian Nynorsk) Currently translated at 67.2% (1288 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/nn/ Translated using Weblate Translated using Weblate (Dutch) Currently translated at 81.5% (1562 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/nl/ Translated using Weblate Translated using Weblate (Lithuanian) Currently translated at 67.2% (1288 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/lt/ Translated using Weblate Translated using Weblate (Korean) Currently translated at 55.8% (1070 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ko/ Translated using Weblate Translated using Weblate (Japanese) Currently translated at 61.5% (1179 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ja/ Translated using Weblate Translated using Weblate (Italian) Currently translated at 100.0% (1916 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/it/ Translated using Weblate Translated using Weblate (Italian) Currently translated at 100.0% (1916 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/it/ Translated using Weblate Translated using Weblate (Hungarian) Currently translated at 85.5% (1640 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/hu/ Translated using Weblate Translated using Weblate (Croatian) Currently translated at 24.3% (466 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/hr/ Translated using Weblate Translated using Weblate (Hebrew) Currently translated at 43.9% (843 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/he/ Translated using Weblate Translated using Weblate (Galician) Currently translated at 85.4% (1637 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/gl/ Translated using Weblate Translated using Weblate (French) Currently translated at 95.7% (1835 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/fr/ Translated using Weblate Translated using Weblate (Finnish) Currently translated at 80.3% (1539 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/fi/ Translated using Weblate Translated using Weblate (Basque) Currently translated at 80.3% (1539 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/eu/ Translated using Weblate Translated using Weblate (Estonian) Currently translated at 79.2% (1518 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/et/ Translated using Weblate Translated using Weblate (Spanish) Currently translated at 95.5% (1830 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/es/ Translated using Weblate Translated using Weblate (Greek) Currently translated at 70.6% (1354 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/el/ Translated using Weblate Translated using Weblate (German) Currently translated at 86.6% (1661 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/de/ Translated using Weblate Translated using Weblate (Danish) Currently translated at 24.0% (460 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/da/ Translated using Weblate Translated using Weblate (Czech) Currently translated at 65.3% (1253 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/cs/ Translated using Weblate Translated using Weblate (Catalan) Currently translated at 81.7% (1566 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ca/ Translated using Weblate Translated using Weblate (Bulgarian) Currently translated at 13.4% (257 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/bg/ Translated using Weblate Translated using Weblate (Asturian) Currently translated at 74.7% (1432 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ast/ Translated using Weblate Translated using Weblate (Arabic) Currently translated at 15.8% (304 of 1916 strings) Translation: aMule/Application Translate-URL: https://hosted.weblate.org/projects/amule/amule-application/ar/ Co-authored-by: Andrei Stepanov <[email protected]> Co-authored-by: Diego Heras <[email protected]> Co-authored-by: Got3nks <[email protected]> Co-authored-by: தமிழ்நேரம் <[email protected]> Co-authored-by: ℂ𝕠𝕠𝕠𝕝 (𝕘𝕚𝕥𝕙𝕦𝕓.𝕔𝕠𝕞/ℂ𝕠𝕠𝕠𝕝) <[email protected]>
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
Fixes #761. After the defer-hash work,
FlushBuffer's Phase 3 enqueues to the async hash thread only whenm_iWrites == 0and no block has arrived in the last 1s. A continuously downloading file keeps both gates engaged, soOnAsyncHashCompletenever fires,SafeAddKFileis never called, and the partfile stays out of the "Shared files" list until the user pauses, restarts, or the download completes. 2.3.3 (pre-async-hash) hashed synchronously the moment a part became complete, which is the behavior danim7 noted as missing.Fix
Add a first-share early path in
FlushBuffer:status == PS_EMPTY && GetHashCount() == GetED2KPartHashCount() && !m_hashsetneeded && m_pendingHashes == 0 && !m_gaplist.IsComplete().m_aChangedPartfor one gap-complete part, then walksm_BufferedData_listto make sure noPB_READY/PB_PENDING/PB_ERRORwrite overlaps that part —FillGapruns at queue time inWriteToBuffer, soIsComplete(N)can be true while a write to N is still buffered and hashing would read pre-write bytes.SafeAddKFilefires fromOnAsyncHashCompleteon the first success, status flips toPS_READY, and the path is dormant for the rest of the session. On a corrupt first part,m_pendingHashesreturns to 0 and status staysPS_EMPTY, so the nextFlushBuffertick picks another candidate — self-arming until something verifies.The destructor / shutdown gate is hoisted above the
m_iWritescheck so the new path inherits it.Test plan
fromAICHRecoveryDataAvailable=true) propagated unchanged