Skip to content

Conversation

@gpshead
Copy link
Member

@gpshead gpshead commented Nov 12, 2025

This splits the OS API specific functionality to get the number of threads out from the fallback Python method and warning raising code itself. This way the OS APIs can be queried before we've run
os.register_at_fork(after_in_parent=...) registered functions which themselves may (re)start threads that would otherwise be detected.

This is best effort. If the OS APIs are either unavailable or fail, the warning generating code still falls back to looking at the Python threading state after the CPython interpreter world has been restarted and the after_in_parent calls have been made. The common case for most Linux and macOS environments should work today.

This also lines up with the existing TODO refactoring, we may choose to expose this API to get the number of OS threads in the os module in the future.

This splits the OS API specific functionality to get the number of threads out
from the fallback Python method and warning raising code itself.  This way the
OS APIs can be queried before we've run
`os.register_at_fork(after_in_parent=...)` registered functions which
themselves may (re)start threads that would otherwise be detected.

This is best effort.  If the OS APIs are either unavailable or fail, the
warning generating code still falls back to looking at the Python threading
state after the CPython interpreter world has been restarted and the
after_in_parent calls have been made.  The common case for most Linux and macOS
environments should work today.

This also lines up with the existing TODO refactoring, we may choose to expose
this API to get the number of OS threads in the `os` module in the future.
@gpshead gpshead self-assigned this Nov 12, 2025
@gpshead gpshead added OS-mac stdlib Standard Library Python modules in the Lib/ directory extension-modules C modules in the Modules dir OS-freebsd OS-linux OS-netbsd labels Nov 12, 2025
Comment on lines +8631 to +8632
// Called before AfterFork_Parent in case those hooks start threads.
Py_ssize_t num_os_threads = get_number_of_os_threads();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other comment on the issue was if we should make this call right after BeforeFork but before the fork call itself. I don't think it makes a lot of difference. This in theory is slightly faster as it runs in parallel with the new child, but might have the downside that actual posix pthread_atfork C library call users could have their own parent callback start a thread from C which we're still missing?

3.13 has been in use for over a year now and that hasn't come up so I'm inclined to leave this on this side of the fork for now as the code is slightly simpler.

@gpshead gpshead requested a review from colesbury November 12, 2025 01:40
@gpshead gpshead added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes type-bug An unexpected behavior, bug, or error labels Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core review extension-modules C modules in the Modules dir needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes OS-freebsd OS-linux OS-mac OS-netbsd stdlib Standard Library Python modules in the Lib/ directory type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant