Skip to content

Commit f4fceed

Browse files
Add FFI definitions from pythread.h
1 parent 5c363b5 commit f4fceed

File tree

5 files changed

+155
-3
lines changed

5 files changed

+155
-3
lines changed

newsfragments/4872.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add FFI definitions from `pythread.h`.

pyo3-ffi/src/cpython/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub(crate) mod descrobject;
1313
pub(crate) mod dictobject;
1414
// skipped fileobject.h
1515
// skipped fileutils.h
16+
pub(crate) mod floatobject;
1617
pub(crate) mod frameobject;
1718
pub(crate) mod funcobject;
1819
pub(crate) mod genobject;
@@ -30,14 +31,14 @@ pub(crate) mod object;
3031
pub(crate) mod objimpl;
3132
pub(crate) mod pydebug;
3233
pub(crate) mod pyerrors;
34+
pub(crate) mod pyframe;
3335
#[cfg(all(Py_3_8, not(PyPy)))]
3436
pub(crate) mod pylifecycle;
3537
pub(crate) mod pymem;
3638
pub(crate) mod pystate;
3739
pub(crate) mod pythonrun;
40+
pub(crate) mod pythread;
3841
// skipped sysmodule.h
39-
pub(crate) mod floatobject;
40-
pub(crate) mod pyframe;
4142
pub(crate) mod tupleobject;
4243
pub(crate) mod unicodeobject;
4344
pub(crate) mod weakrefobject;
@@ -78,6 +79,7 @@ pub use self::pylifecycle::*;
7879
pub use self::pymem::*;
7980
pub use self::pystate::*;
8081
pub use self::pythonrun::*;
82+
pub use self::pythread::*;
8183
pub use self::tupleobject::*;
8284
pub use self::unicodeobject::*;
8385
#[cfg(not(any(PyPy, GraalPy)))]

pyo3-ffi/src/cpython/pythread.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::os::raw::c_int;
2+
#[cfg(not(PyPy))]
3+
use std::os::raw::c_longlong;
4+
#[cfg(target_os = "wasi")]
5+
use std::os::raw::c_uint;
6+
#[cfg(any(not(PyPy), windows))]
7+
use std::os::raw::c_ulong;
8+
9+
#[cfg(all(not(PyPy), not(Py_3_13), not(windows)))]
10+
pub const PY_TIMEOUT_MAX: c_longlong = c_longlong::MAX / 1000;
11+
#[cfg(all(not(PyPy), not(Py_3_11), windows))]
12+
pub const PY_TIMEOUT_MAX: c_longlong = (0xFFFFFFFF as c_longlong).saturating_mul(1000);
13+
#[cfg(all(not(PyPy), Py_3_11, not(Py_3_13), windows))]
14+
pub const PY_TIMEOUT_MAX: c_longlong = (0xFFFFFFFE as c_longlong).saturating_mul(1000);
15+
#[cfg(all(not(any(PyPy, GraalPy)), Py_3_13))]
16+
#[cfg_attr(windows, link(name = "pythonXY"))]
17+
extern "C" {
18+
pub static PY_TIMEOUT_MAX: c_longlong;
19+
}
20+
21+
#[cfg(not(PyPy))]
22+
pub const PYTHREAD_INVALID_THREAD_ID: c_ulong = c_ulong::MAX;
23+
24+
// skipped _PyThread_at_fork_reinit (removed 3.13)
25+
26+
#[cfg(not(any(windows, target_os = "wasi")))]
27+
type NATIVE_TSS_KEY_T = libc::pthread_key_t;
28+
#[cfg(windows)]
29+
type NATIVE_TSS_KEY_T = c_ulong;
30+
#[cfg(target_os = "wasi")]
31+
type NATIVE_TSS_KEY_T = c_uint;
32+
33+
#[repr(C)]
34+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
35+
pub struct Py_tss_t {
36+
_is_initialized: c_int,
37+
_key: NATIVE_TSS_KEY_T,
38+
}
39+
40+
impl Default for Py_tss_t {
41+
fn default() -> Self {
42+
Py_tss_NEEDS_INIT
43+
}
44+
}
45+
46+
pub const Py_tss_NEEDS_INIT: Py_tss_t = Py_tss_t {
47+
_is_initialized: 0,
48+
_key: 0,
49+
};

pyo3-ffi/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ pub use self::pyport::*;
438438
pub use self::pystate::*;
439439
pub use self::pystrtod::*;
440440
pub use self::pythonrun::*;
441+
pub use self::pythread::*;
441442
pub use self::rangeobject::*;
442443
pub use self::setobject::*;
443444
pub use self::sliceobject::*;
@@ -528,7 +529,7 @@ mod pythonrun;
528529
// skipped pystrhex.h
529530
// skipped pystrcmp.h
530531
mod pystrtod;
531-
// skipped pythread.h
532+
mod pythread;
532533
// skipped pytime.h
533534
mod rangeobject;
534535
mod setobject;

pyo3-ffi/src/pythread.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use crate::object::PyObject;
2+
#[cfg(not(PyPy))]
3+
use std::os::raw::c_longlong;
4+
use std::os::raw::{c_int, c_ulong, c_void};
5+
6+
pub type PyThread_type_lock = *mut c_void;
7+
// skipped PyThread_type_sema (removed 3.9)
8+
9+
#[cfg(not(PyPy))]
10+
#[repr(C)]
11+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12+
pub enum PyLockStatus {
13+
PY_LOCK_FAILURE = 0,
14+
PY_LOCK_ACQUIRED = 1,
15+
PY_LOCK_INTR,
16+
}
17+
18+
extern "C" {
19+
pub fn PyThread_init_thread();
20+
pub fn PyThread_start_new_thread(
21+
arg1: Option<unsafe extern "C" fn(*mut c_void)>,
22+
arg2: *mut c_void,
23+
) -> c_ulong;
24+
25+
// skipped PyThread_exit_thread (deprecated 3.14)
26+
27+
pub fn PyThread_get_thread_ident() -> c_ulong;
28+
29+
#[cfg(all(
30+
not(PyPy),
31+
any(
32+
target_os = "ios",
33+
target_os = "macos",
34+
target_os = "tvos",
35+
target_os = "watchos",
36+
target_os = "android",
37+
target_os = "linux",
38+
target_os = "windows",
39+
target_os = "freebsd",
40+
target_os = "openbsd",
41+
target_os = "netbsd",
42+
all(not(GraalPy), Py_3_12, target_os = "dragonfly"),
43+
target_os = "aix"
44+
)
45+
))]
46+
pub fn PyThread_get_thread_native_id() -> c_ulong;
47+
48+
pub fn PyThread_allocate_lock() -> PyThread_type_lock;
49+
pub fn PyThread_free_lock(arg1: PyThread_type_lock);
50+
pub fn PyThread_acquire_lock(arg1: PyThread_type_lock, arg2: c_int) -> c_int;
51+
}
52+
53+
pub const WAIT_LOCK: c_int = 1;
54+
pub const NOWAIT_LOCK: c_int = 0;
55+
56+
#[cfg(not(PyPy))]
57+
pub type PY_TIMEOUT_T = c_longlong;
58+
59+
extern "C" {
60+
#[cfg(not(PyPy))]
61+
pub fn PyThread_acquire_lock_timed(
62+
arg1: PyThread_type_lock,
63+
microseconds: PY_TIMEOUT_T,
64+
intr_flag: c_int,
65+
) -> PyLockStatus;
66+
67+
pub fn PyThread_release_lock(arg1: PyThread_type_lock);
68+
69+
#[cfg(not(PyPy))]
70+
pub fn PyThread_get_stacksize() -> usize;
71+
72+
#[cfg(not(PyPy))]
73+
pub fn PyThread_set_stacksize(arg1: usize) -> c_int;
74+
75+
#[cfg(not(PyPy))]
76+
pub fn PyThread_GetInfo() -> *mut PyObject;
77+
78+
// skipped PyThread_create_key (deprecated 3.7)
79+
// skipped PyThread_delete_key (deprecated 3.7)
80+
// skipped PyThread_set_key_value (deprecated 3.7)
81+
// skipped PyThread_get_key_value (deprecated 3.7)
82+
// skipped PyThread_delete_key_value (deprecated 3.7)
83+
// skipped PyThread_ReInitTLS (deprecated 3.7)
84+
}
85+
86+
#[cfg(Py_LIMITED_API)]
87+
opaque_struct!(Py_tss_t);
88+
#[cfg(not(Py_LIMITED_API))]
89+
use crate::cpython::pythread::Py_tss_t;
90+
91+
extern "C" {
92+
pub fn PyThread_tss_alloc() -> *mut Py_tss_t;
93+
pub fn PyThread_tss_free(key: *mut Py_tss_t);
94+
pub fn PyThread_tss_is_created(key: *mut Py_tss_t) -> c_int;
95+
pub fn PyThread_tss_create(key: *mut Py_tss_t) -> c_int;
96+
pub fn PyThread_tss_delete(key: *mut Py_tss_t);
97+
pub fn PyThread_tss_set(key: *mut Py_tss_t, value: *mut c_void) -> c_int;
98+
pub fn PyThread_tss_get(key: *mut Py_tss_t) -> *mut c_void;
99+
}

0 commit comments

Comments
 (0)