-
Notifications
You must be signed in to change notification settings - Fork 847
Add FFI definitions from pythread.h
#4872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
400c8c5
to
8a431d6
Compare
Hmm, I'm not entirely sure how to replicate the #ifdef HAVE_PTHREAD_H
# include <pthread.h>
# define NATIVE_TSS_KEY_T pthread_key_t
#elif defined(NT_THREADS)
# define NATIVE_TSS_KEY_T unsigned long
#elif defined(HAVE_PTHREAD_STUBS)
# include "cpython/pthread_stubs.h"
# define NATIVE_TSS_KEY_T pthread_key_t
#else
# error "Require native threads. See https://bugs.python.org/issue31370"
#endif It might make sense just to add a carve-out for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR and sorry for the wait. The PR looks good to me, just I think we should do away with the exit function. Regarding the ci failure, libc::pthread_key_t
is not defined on all platforms. I'm not sure how exactly libc defines it but it'd be best to just follow that, I think.
f46fa95
to
f4fceed
Compare
Alright, I've replaced (As for following whatever |
f4fceed
to
371275c
Compare
That sounds reasonable, can you please add a comment about that?
That does seem the simplest. Can you sprinkle a bunch of Anyway, I've been looking at the definition of I think we should try to mirror the python files as much as possible...I'm happy for ideas here. /// private helper for `PY_TIMEOUT_MAX`
const LLONG_MAX: c_longlong = ...;
/// Note: This is a static on 3.13 and up, thank the gods
#[cfg_attr(docsrs, doc(cfg(not(PyPy))))]
#[cfg(all(not(PyPy), not(Py_3_13)))]
pub const PY_TIMEOUT_MAX: c_longlong = if cfg!(Py_3_12) {
if cfg!(not(windows)) {
LLONG_MAX / 1000
} else if cfg!(windows) {
if 0xFFFFFFFELL.saturating_mul(1000) < LLONG_MAX {
0xFFFFFFFELL.saturating_mul(1000)
} else {
LLONG_MAX
}
} else {
LLONG_MAX
}
} else if cfg!(Py_3_11) {
} else if cfg!(Py_3_10) {
} else if cfg!(Py_3_9) {
} else if cfg!(Py_3_8) {
} else {
panic!()
}; There's also a definition for 3.7 which would need to live in |
Sure, will do, once I get the other stuff sorted out.
Sorry, how exactly do these
I copied the different versions as best I could. The change in CPython 3.11 (mirrored in GraalPy 24.1.0) is what these two separate lines are for: #[cfg(all(not(PyPy), not(Py_3_11), windows))]
pub const PY_TIMEOUT_MAX: c_longlong = (0xFFFFFFFF as c_longlong).saturating_mul(1000);
#[cfg(all(not(PyPy), Py_3_11, not(Py_3_13), windows))]
pub const PY_TIMEOUT_MAX: c_longlong = (0xFFFFFFFE as c_longlong).saturating_mul(1000); I use a One lingering question: If neither
In fact, it existed in the limited |
Reading these header files gives me a headache. Is this constant actually useful? I'm leaning towards just omitting everything but the static version.
The problem is when you have something like #[cfg(Py_3_10)]
pub const X = 10;
#[cfg(not(Py_3_10))]
pub const X = 5; then if (say) the environment has a python 3.11 available and pyo3 detects that, it will be marked as "this is only available on 3.10 and up". doc_cfg lets you override that, and with Or (in this case) you can do
See https://github.com/PyO3/pyo3/blob/main/Contributing.md#help-write-great-docs
I agree, I read that PR as "it was never documented as being in the stable api", therefore it isn't. |
This PR adds all definitions from
pythread.h
andcpython/pythread.h
that haven't been deprecated or removed as of CPython 3.13. Of the functions, some are fully documented, some are undocumented but still contained in the limited API list, and some are neither documented nor in the limited API. Some of the limited-API functions, such asPyThread_get_thread_ident()
, are widely used by 3rd-party code despite being undocumented, so it would be useful to include them in the bindings. The full breakdown:PyThread_tss_alloc
,PyThread_tss_create
,PyThread_tss_delete
,PyThread_tss_free
,PyThread_tss_get
,PyThread_tss_is_created
,PyThread_tss_set
; structPy_tss_t
.PyThread_GetInfo
,PyThread_acquire_lock
,PyThread_acquire_lock_timed
,PyThread_allocate_lock
,PyThread_exit_thread
,PyThread_free_lock
,PyThread_get_stacksize
,PyThread_get_thread_ident
,PyThread_get_thread_native_id
,PyThread_init_thread
,PyThread_release_lock
,PyThread_set_stacksize
,PyThread_start_new_thread
; enumPyLockStatus
; typedefsPY_TIMEOUT_T
,PyThread_type_lock
; constantsNOWAIT_LOCK
,PY_LOCK_ACQUIRED
,PY_LOCK_FAILURE
,PY_LOCK_INTR
,WAIT_LOCK
.Py_tss_NEEDS_INIT
.PY_TIMEOUT_MAX
; constantPYTHREAD_INVALID_THREAD_ID
.PyThread_get_thread_native_id()
is a particularly fiddly definition due to all the OS-based#ifdef
s guarding it: I've approximated them withcfg(target_os)
values to the best of my ability, but it would be much easier if we could directly check that thePY_HAVE_THREAD_NATIVE_ID
macro is defined. I've also gone through the PyPy and GraalPy versions of the headers to see which functions they support.