Replace window-message async hostname resolver with worker-thread model
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¶
CDownloadQueue resolves hostnames for download sources using WSAAsyncGetHostByName(),
a Windows-only API that posts a window message when resolution completes. This API:
- Is marked deprecated since Windows Vista
- Routes through a hidden helper window (same fragility as WSAAsyncSelect)
- Processes only one resolution at a time per helper window slot
- Cannot be cancelled cleanly without destroying the window
The experimental branch replaces this with a proper worker thread pool that resolves
hostnames asynchronously and posts results to the main thread via message, eliminating the
WSAAsyncGetHostByName dependency entirely.
Current Status¶
This refactor is now landed on current main:
- app commit
aa031be—REF-030 replace download source async DNS
Current CDownloadQueue owns a CSourceHostnameResolver with a std::thread,
uses getaddrinfo(), and drains resolved source addresses back on the download
queue path. DownloadQueue.cpp no longer calls WSAAsyncGetHostByName.
Any future expansion from one resolver worker to a small bounded resolver pool
is no longer part of REF-030. It is tracked separately as FEAT-081 and should
only be implemented if profiling shows hostname resolution backlog.
Revalidation — 2026-04-14¶
Current main still has WSAAsyncGetHostByName in more places than just
CDownloadQueue.
Live call / reply sites now visible in the tree are:
AsyncSocketEx.cpp:498,904DownloadQueue.cpp:1481,1517,1555EmuleDlg.cpp:713,715UDPSocket.cpp:98,802
This item remains scoped to the DownloadQueue consumer because that is the
slice with an audited experimental reference implementation today.
Implementation note: landing REF-030 will not eliminate all message-based
DNS in the codebase by itself. AsyncSocketEx, EmuleDlg, and UDPSocket
still need either follow-on backlog items or deliberate opportunistic cleanup
when those subsystems are touched.
Experimental Reference Implementation¶
Source: stale-v0.72a-experimental-clean, commit 810c3c7 FIX: replace download source
async hostname window resolver (270 insertions / 139 deletions)
New file:
- srchybrid/DownloadQueueHostnameResolverSeams.h — resolver abstraction seam (+34 lines)
Modified files:
- srchybrid/DownloadQueue.cpp — new CDownloadQueueHostnameResolver class using
std::thread + std::queue for hostname resolution (+169/-139 lines)
- srchybrid/DownloadQueue.h — resolver member and interface (+48 lines)
Architecture:
[Old] WSAAsyncGetHostByName() → helper window → WM_HOSTNAME_RESOLVED → handler
[New] Worker thread → getaddrinfo() → PostMessage(WM_HOSTNAME_RESULT) → handler
The worker thread pool (or single thread) calls getaddrinfo() (the modern replacement for
gethostbyname), then posts a WM_HOSTNAME_RESULT message to the download queue window
with the resolved address.
Benefits¶
- Eliminates deprecated
WSAAsyncGetHostByName(WWMOD_030 / REF-021 adjacent) - Enables concurrent hostname resolutions (multiple worker threads)
- Cancellation is clean: signal the worker queue and drain
getaddrinfosupports IPv6, unlikegethostbyname- Prepares for future IPv6/dual-stack source sources (WWMOD_025)
Dependency¶
- REF-021 (remove deprecated Winsock APIs): REF-030 is a concrete instance of the
WSAAsyncGetHostByNamedeprecation; coordinate - WWMOD_030 (deprecated Winsock APIs — Done):
WSAAsyncGetHostByNameis in the same category; this REF explicitly targets the download queue consumer - REF-008 (Boost.Asio): Asio's resolver (
asio::ip::tcp::resolver) would supersede this entirely — REF-030 is a stepping stone if Boost is not adopted
Acceptance Criteria¶
- [x]
WSAAsyncGetHostByNamenot called anywhere inDownloadQueue.cpp - [x] Hostname resolution uses
getaddrinfoin a worker thread - [x] Cancellation of pending resolutions works without leaks
- [x] No regression in add-source-by-hostname workflow
- [ ] IPv6 address results handled (deferred to the IPv6 roadmap rather than required for the current IPv4 source path)