Skip to content

WebSocket accepted-client tracking is not exception-safe after thread start

Summary

The WebSocket accept path starts an accepted-client thread and then records the thread state in the accepted-thread tracking vector. If vector allocation throws after the thread starts, the thread can keep running with m_bAutoDelete = FALSE, but shutdown no longer knows to join or reap it.

This is a major Beta 0.7.3 blocker because the failure path converts memory pressure into an untracked live thread, which can later collide with shutdown lifetime and WebSocket restart safety.

Evidence

  • srchybrid/WebSocket.cpp:743 starts the accepted WebSocket client thread.
  • srchybrid/WebSocket.cpp:748 tracks the accepted-client thread after start.
  • srchybrid/WebSocket.cpp:190-192 uses an unguarded s_acceptedThreads.push_back(state).
  • The accepted thread uses explicit lifetime management rather than MFC auto-delete, so an untracked started thread is not benign.

Execution Plan

  1. Revalidate accepted-client thread creation, ownership, and cleanup on current main.
  2. Make accepted-thread tracking exception-safe before or at the moment the thread can run.
  3. Prefer reserving/tracking a pending state before resume/start, or introduce a guard that owns the socket and CWinThread until the state is successfully tracked.
  4. If tracking fails after thread creation, signal shutdown for that accepted client, close its socket through the correct owner, and join/delete the thread object deterministically.
  5. Keep existing shutdown drain and restart-safety behavior intact.
  6. Add a focused allocation-failure seam around accepted-thread tracking.

Acceptance Criteria

  • No accepted WebSocket client thread can run untracked.
  • Allocation failure during tracking closes or joins the accepted client without leaking socket, thread, or SSL state.
  • HTTP and HTTPS accepted-client shutdown behavior remains compatible.
  • WebSocket restart-safety protections from prior Beta 0.7.3 fixes remain intact.
  • The item has commit evidence and targeted validation in this file before Beta 0.7.3.

Validation

  • 2026-05-08: Done in app commit 219be75.
  • python -m emule_workspace validate --workspace-root . passed.
  • python -m emule_workspace build app --workspace-root . --config Release --platform x64 --variant main passed; log root workspaces\v0.72a\state\build-logs\20260508-102546.
  • python -m emule_workspace build app --workspace-root . --config Debug --platform x64 --variant main passed; log root workspaces\v0.72a\state\build-logs\20260508-102607.
  • Code validation: accepted WebSocket client threads are now inserted into the tracked-thread list before CreateThread starts them. If tracking allocation fails, the thread has not started and the accept path deletes the wrapper, deletes the socket data, and closes the accepted socket.