Skip to content

fix: observe terminated workers and report safe_terminate outcome - #431

Open
inchang-ing wants to merge 1 commit into
pytest-dev:mainfrom
inchang-ing:safe-terminate-join-and-report
Open

inchang-ing wants to merge 1 commit into
pytest-dev:mainfrom
inchang-ing:safe-terminate-join-and-report

Conversation

@inchang-ing

Copy link
Copy Markdown

Fixes #429

Problem

safe_terminate abandons the worker thread running termfunc once the kill attempt is made, and reports success regardless:

  1. In termkill, when termreply.get(timeout=timeout) times out (OSError), killfunc() runs and termkill returns — nothing waits for the termfunc worker afterwards. These workers are started via _thread.start_new_thread, so threading._shutdown() never joins them; they can outlive safe_terminate arbitrarily (observed via pytest-xdist teardown faulthandler dumps, as described in the issue).
  2. WorkerPool.waitall() returns bool, but safe_terminate discarded it — so Group.terminate() reports success even while abandoned workers are demonstrably still running.

(The unbounded reply.get() mentioned in the issue was already bounded by commit f700163.)

Change

  • In termkill, after killfunc(), wait once more for the termfunc worker with the same timeout bound. A kill that releases the worker lets it be joined; a kill that does not is swallowed there and reported through the pool wait instead. Worst-case bound grows by at most one timeout interval, still fully bounded.
  • safe_terminate now returns WorkerPool.waitall(timeout=wait_timeout) (None → bool signature change, backward compatible since callers previously had no return value) and its docstring documents the meaning: False means some termfunc was still running and its thread was abandoned. Group.terminate keeps ignoring the value; pytest-xdist-style callers can now use it.

Testing

  • test_safe_terminate_reports_kill_that_ignores: a no-op killfunc leaves the termfunc blocked; safe_terminate now returns False (fails on pre-fix code — verified via git stash).
  • test_safe_terminate_joins_when_kill_releases: a killfunc that releases the termfunc yields True with the worker observed finished immediately on return.
  • Full testing/test_multi.py: 26 passed, 11 skipped, 11 xfailed, 2 xpassed (the xpass/xskip are pre-existing markers).

Disclosure

This PR was prepared with AI assistance (ZCode/GLM, orchestrated via WorkBuddy).

After the kill attempt, wait once more (bounded by the same timeout)
for the termfunc worker, so a kill that releases it lets the worker be
joined instead of abandoned while still running. Threads spawned via
_thread.start_new_thread are never joined by threading._shutdown, so
abandoned workers could outlive safe_terminate arbitrarily.

safe_terminate now also returns the WorkerPool.waitall result instead
of discarding it, letting Group.terminate and other callers tell
whether all workers actually finished within the bounds.

Fixes pytest-dev#429

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

safe_terminate() leaves the abandoned termfunc thread running and reports success anyway

1 participant