Skip to content

Replace window-message async hostname resolver with worker-thread model

Historical reference only: stale-v0.72a-experimental-clean and analysis\stale-v0.72a-experimental-clean are retired reference sources, not active branch targets or current baselines. Use them only as provenance or idea-extraction sources; landed status is determined against main. 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 aa031beREF-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,904
  • DownloadQueue.cpp:1481,1517,1555
  • EmuleDlg.cpp:713,715
  • UDPSocket.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
  • getaddrinfo supports IPv6, unlike gethostbyname
  • 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 WSAAsyncGetHostByName deprecation; coordinate
  • WWMOD_030 (deprecated Winsock APIs — Done): WSAAsyncGetHostByName is 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] WSAAsyncGetHostByName not called anywhere in DownloadQueue.cpp
  • [x] Hostname resolution uses getaddrinfo in 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)