mirror of
https://github.com/element-hq/synapse.git
synced 2026-11-12 16:27:54 +00:00
To use `reactor.callFromThread` we need to take the GIL. However, the vast majority of use-cases on the Rust side involve using that from Tokio reactor threads, where we do not want to take the GIL (as it can potentially block for a long time). In #20252 we added a pure Rust alternative to `callFromThread`. `run_python_awaitable` is the last usage of `callFromThread`, and so we replace it with `dispatch_to_twisted`. --- The diff is a lot smaller if you hide pure whitespace changes. --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
63 lines
1.9 KiB
Rust
63 lines
1.9 KiB
Rust
/*
|
|
* This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
*
|
|
* Copyright (C) 2026 Element Creations Ltd
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* See the GNU Affero General Public License for more details:
|
|
* <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
*
|
|
*/
|
|
|
|
//! A typed wrapper around the Twisted reactor.
|
|
|
|
use pyo3::{intern, prelude::*};
|
|
|
|
/// The Twisted reactor, as seen from Rust.
|
|
///
|
|
/// This is a wrapper around a foreign Python object. No validation is
|
|
/// performed, on the assumption the Python side is correctly typed.
|
|
pub struct Reactor(Py<PyAny>);
|
|
|
|
impl<'a, 'py> FromPyObject<'a, 'py> for Reactor {
|
|
type Error = PyErr;
|
|
|
|
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
|
|
Ok(Reactor(obj.to_owned().unbind()))
|
|
}
|
|
}
|
|
|
|
impl Reactor {
|
|
/// `reactor.addReader(reader)`: have the reactor poll `reader.fileno()`
|
|
/// and call `reader.doRead()` when it is readable.
|
|
///
|
|
/// Must be called on the reactor thread.
|
|
pub fn add_reader(&self, py: Python<'_>, reader: &Bound<'_, PyAny>) -> PyResult<()> {
|
|
self.0
|
|
.bind(py)
|
|
.call_method1(intern!(py, "addReader"), (reader,))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// `reactor.removeReader(reader)`: stop polling a reader added with
|
|
/// [`Reactor::add_reader`]. A no-op if it was never added.
|
|
///
|
|
/// Must be called on the reactor thread.
|
|
pub fn remove_reader(&self, py: Python<'_>, reader: &Bound<'_, PyAny>) -> PyResult<()> {
|
|
self.0
|
|
.bind(py)
|
|
.call_method1(intern!(py, "removeReader"), (reader,))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn clone_ref(&self, py: Python<'_>) -> Reactor {
|
|
Reactor(self.0.clone_ref(py))
|
|
}
|
|
}
|