mirror of
https://github.com/emmett-framework/granian.git
synced 2025-07-07 19:35:33 +00:00
Add PyPy specific code for CallbackScheduler
(#462)
This commit is contained in:
parent
0e1c043fb1
commit
727d80b563
4 changed files with 108 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -485,6 +485,7 @@ dependencies = [
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
"pyo3",
|
"pyo3",
|
||||||
|
"pyo3-build-config",
|
||||||
"pyo3-log",
|
"pyo3-log",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
|
|
@ -59,6 +59,9 @@ mimalloc = { version = "0.1.43", default-features = false, features = ["local_dy
|
||||||
[target.'cfg(not(any(target_os = "freebsd", target_os = "windows")))'.dependencies]
|
[target.'cfg(not(any(target_os = "freebsd", target_os = "windows")))'.dependencies]
|
||||||
tikv-jemallocator = { version = "0.6.0", default-features = false, features = ["disable_initial_exec_tls"] }
|
tikv-jemallocator = { version = "0.6.0", default-features = false, features = ["disable_initial_exec_tls"] }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
pyo3-build-config = { version = "=0.23", features = ["resolve-config"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
debug = false
|
debug = false
|
||||||
|
|
3
build.rs
Normal file
3
build.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
pyo3_build_config::use_pyo3_cfgs();
|
||||||
|
}
|
101
src/callbacks.rs
101
src/callbacks.rs
|
@ -24,6 +24,7 @@ pub(crate) struct CallbackScheduler {
|
||||||
pyfalse: PyObject,
|
pyfalse: PyObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(PyPy))]
|
||||||
impl CallbackScheduler {
|
impl CallbackScheduler {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn schedule(&self, _py: Python, watcher: &PyObject) {
|
pub(crate) fn schedule(&self, _py: Python, watcher: &PyObject) {
|
||||||
|
@ -113,6 +114,106 @@ impl CallbackScheduler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(PyPy)]
|
||||||
|
impl CallbackScheduler {
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn schedule(&self, py: Python, watcher: &PyObject) {
|
||||||
|
let cbarg = (watcher,).into_pyobject(py).unwrap().into_ptr();
|
||||||
|
let sched = self.schedule_fn.get().unwrap().as_ptr();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pyo3::ffi::PyObject_CallObject(sched, cbarg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn send(pyself: Py<Self>, py: Python, coro: PyObject) {
|
||||||
|
let rself = pyself.get();
|
||||||
|
let ptr = (pyself.clone_ref(py),).into_pyobject(py).unwrap().into_ptr();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pyo3::ffi::PyObject_CallObject(rself.aio_tenter.as_ptr(), ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(res) = unsafe {
|
||||||
|
let res = pyo3::ffi::PyObject_CallMethodObjArgs(
|
||||||
|
coro.as_ptr(),
|
||||||
|
rself.pyname_aiosend.as_ptr(),
|
||||||
|
rself.pynone.as_ptr(),
|
||||||
|
std::ptr::null_mut::<PyObject>(),
|
||||||
|
);
|
||||||
|
Bound::from_owned_ptr_or_err(py, res)
|
||||||
|
} {
|
||||||
|
if unsafe {
|
||||||
|
let vptr = pyo3::ffi::PyObject_GetAttr(res.as_ptr(), rself.pyname_aioblock.as_ptr());
|
||||||
|
Bound::from_owned_ptr_or_err(py, vptr)
|
||||||
|
.map(|v| v.extract::<bool>().unwrap_or(false))
|
||||||
|
.unwrap_or(false)
|
||||||
|
} {
|
||||||
|
let waker = Py::new(
|
||||||
|
py,
|
||||||
|
CallbackSchedulerWaker {
|
||||||
|
sched: pyself.clone_ref(py),
|
||||||
|
coro,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let resp = res.as_ptr();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pyo3::ffi::PyObject_SetAttr(resp, rself.pyname_aioblock.as_ptr(), rself.pyfalse.as_ptr());
|
||||||
|
pyo3::ffi::PyObject_CallMethodObjArgs(
|
||||||
|
resp,
|
||||||
|
rself.pyname_donecb.as_ptr(),
|
||||||
|
waker.as_ptr(),
|
||||||
|
std::ptr::null_mut::<PyObject>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let sref = Py::new(
|
||||||
|
py,
|
||||||
|
CallbackSchedulerRef {
|
||||||
|
sched: pyself.clone_ref(py),
|
||||||
|
coro,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pyo3::ffi::PyObject_CallMethodObjArgs(
|
||||||
|
#[allow(clippy::used_underscore_binding)]
|
||||||
|
rself._loop.as_ptr(),
|
||||||
|
rself.pyname_loopcs.as_ptr(),
|
||||||
|
sref.as_ptr(),
|
||||||
|
std::ptr::null_mut::<PyObject>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pyo3::ffi::PyObject_CallObject(rself.aio_texit.as_ptr(), ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn throw(pyself: Py<Self>, py: Python, coro: PyObject, err: PyObject) {
|
||||||
|
let pyname_aiothrow = pyself.get().pyname_aiothrow.as_ptr();
|
||||||
|
let aio_tenter = pyself.get().aio_tenter.as_ptr();
|
||||||
|
let aio_texit = pyself.get().aio_texit.as_ptr();
|
||||||
|
let ptr = (pyself,).into_py_any(py).unwrap().as_ptr();
|
||||||
|
let errptr = (err,).into_py_any(py).unwrap().as_ptr();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let corom = pyo3::ffi::PyObject_GetAttr(coro.as_ptr(), pyname_aiothrow);
|
||||||
|
pyo3::ffi::PyObject_CallObject(aio_tenter, ptr);
|
||||||
|
pyo3::ffi::PyObject_CallObject(corom, errptr);
|
||||||
|
pyo3::ffi::PyErr_Clear();
|
||||||
|
pyo3::ffi::PyObject_CallObject(aio_texit, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl CallbackScheduler {
|
impl CallbackScheduler {
|
||||||
#[new]
|
#[new]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue