mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-22 23:34:49 +01:00
feat(python): summon black magic to allow possible release of the GIL between .awaits
plus nice static runtime singleton fetcher/instantiator
This commit is contained in:
parent
5acca5ce3e
commit
3fe6d224e3
2 changed files with 38 additions and 9 deletions
|
@ -16,22 +16,22 @@ impl CursorController {
|
||||||
buffer: path,
|
buffer: path,
|
||||||
user: None,
|
user: None,
|
||||||
};
|
};
|
||||||
self.send(pos).await
|
super::AllowThreads(self.send(pos)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "try_recv")]
|
#[pyo3(name = "try_recv")]
|
||||||
async fn pytry_recv(&self) -> crate::Result<Option<Cursor>> {
|
async fn pytry_recv(&self) -> crate::Result<Option<Cursor>> {
|
||||||
self.try_recv().await
|
super::AllowThreads(self.try_recv()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "recv")]
|
#[pyo3(name = "recv")]
|
||||||
async fn pyrecv(&self) -> crate::Result<Cursor> {
|
async fn pyrecv(&self) -> crate::Result<Cursor> {
|
||||||
self.recv().await
|
super::AllowThreads(self.recv()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "poll")]
|
#[pyo3(name = "poll")]
|
||||||
async fn pypoll(&self) -> crate::Result<()> {
|
async fn pypoll(&self) -> crate::Result<()> {
|
||||||
self.poll().await
|
super::AllowThreads(self.poll()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "stop")]
|
#[pyo3(name = "stop")]
|
||||||
|
@ -45,7 +45,7 @@ impl CursorController {
|
||||||
impl BufferController {
|
impl BufferController {
|
||||||
#[pyo3(name = "content")]
|
#[pyo3(name = "content")]
|
||||||
async fn pycontent(&self) -> crate::Result<String> {
|
async fn pycontent(&self) -> crate::Result<String> {
|
||||||
self.content().await
|
super::AllowThreads(Box::pin(self.content())).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "send")]
|
#[pyo3(name = "send")]
|
||||||
|
@ -56,22 +56,22 @@ impl BufferController {
|
||||||
content: txt,
|
content: txt,
|
||||||
hash: None,
|
hash: None,
|
||||||
};
|
};
|
||||||
self.send(op).await
|
super::AllowThreads(self.send(op)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "try_recv")]
|
#[pyo3(name = "try_recv")]
|
||||||
async fn pytry_recv(&self) -> crate::Result<Option<TextChange>> {
|
async fn pytry_recv(&self) -> crate::Result<Option<TextChange>> {
|
||||||
self.try_recv().await
|
super::AllowThreads(self.try_recv()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "recv")]
|
#[pyo3(name = "recv")]
|
||||||
async fn pyrecv(&self) -> crate::Result<TextChange> {
|
async fn pyrecv(&self) -> crate::Result<TextChange> {
|
||||||
self.recv().await
|
super::AllowThreads(self.recv()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyo3(name = "poll")]
|
#[pyo3(name = "poll")]
|
||||||
async fn pypoll(&self) -> crate::Result<()> {
|
async fn pypoll(&self) -> crate::Result<()> {
|
||||||
self.poll().await
|
super::AllowThreads(self.poll()).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@ pub mod controllers;
|
||||||
pub mod workspace;
|
pub mod workspace;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
pin::{pin, Pin},
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{Cursor, TextChange},
|
api::{Cursor, TextChange},
|
||||||
|
@ -14,6 +19,30 @@ use pyo3::exceptions::{PyConnectionError, PyRuntimeError, PySystemError};
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
|
|
||||||
|
fn tokio() -> &'static tokio::runtime::Runtime {
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
static RT: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
|
||||||
|
RT.get_or_init(|| tokio::runtime::Runtime::new().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
// workaround to allow the GIL to be released across awaits
|
||||||
|
struct AllowThreads<F>(F);
|
||||||
|
|
||||||
|
impl<F> Future for AllowThreads<F>
|
||||||
|
where
|
||||||
|
F: Future + Unpin + Send,
|
||||||
|
F::Output: Send,
|
||||||
|
{
|
||||||
|
type Output = F::Output;
|
||||||
|
|
||||||
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
let waker = cx.waker();
|
||||||
|
Python::with_gil(|gil| {
|
||||||
|
gil.allow_threads(|| pin!(&mut self.0).poll(&mut Context::from_waker(waker)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<crate::Error> for PyErr {
|
impl From<crate::Error> for PyErr {
|
||||||
fn from(value: crate::Error) -> Self {
|
fn from(value: crate::Error) -> Self {
|
||||||
match value {
|
match value {
|
||||||
|
|
Loading…
Reference in a new issue