fix(dbus): Block on creation of zbus connection to avoid deadlock
A fix for the issue reported in https://github.com/pop-os/cosmic-comp/pull/2450. Using `block_on` in some places for zbus calls is fine (that's what zbus's blocking API does; it has its own executor for background tasks), but this is problematic with `async_once_cell`. If we also use that in the calloop async executor. I think ideally we should avoid blocking the main thread on any async tasks, but for now we can just block in initialization here.
This commit is contained in:
parent
94e9437c4e
commit
5153d497e7
3 changed files with 9 additions and 20 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -242,12 +242,6 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-once-cell"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a"
|
||||
|
||||
[[package]]
|
||||
name = "async-process"
|
||||
version = "2.5.0"
|
||||
|
|
@ -835,7 +829,6 @@ name = "cosmic-comp"
|
|||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-once-cell",
|
||||
"bitflags 2.11.0",
|
||||
"calloop 0.14.4",
|
||||
"cgmath",
|
||||
|
|
|
|||
|
|
@ -83,7 +83,6 @@ logind-zbus = { version = "5.3.2", optional = true }
|
|||
futures-executor = { version = "0.3.32" }
|
||||
futures-util = "0.3.32"
|
||||
cgmath = "0.18.0"
|
||||
async-once-cell = "0.5.4"
|
||||
|
||||
[dependencies.id_tree]
|
||||
branch = "feature/copy_clone"
|
||||
|
|
|
|||
|
|
@ -26,19 +26,21 @@ pub struct DBusState(Rc<DBusStateInner>);
|
|||
struct DBusStateInner {
|
||||
evlh: LoopHandle<'static, State>,
|
||||
executor: calloop::futures::Scheduler<()>,
|
||||
session_conn: async_once_cell::OnceCell<zbus::Connection>,
|
||||
system_conn: async_once_cell::OnceCell<zbus::Connection>,
|
||||
session_conn: zbus::Result<zbus::Connection>,
|
||||
system_conn: zbus::Result<zbus::Connection>,
|
||||
a11y_keyboard_monitor: RefCell<Option<a11y_keyboard_monitor::A11yKeyboardMonitorState>>,
|
||||
}
|
||||
|
||||
impl DBusState {
|
||||
pub fn init(evlh: &LoopHandle<'static, State>) -> Self {
|
||||
let (source, executor) = calloop::futures::executor().unwrap();
|
||||
let session_conn = futures_executor::block_on(zbus::Connection::session());
|
||||
let system_conn = futures_executor::block_on(zbus::Connection::system());
|
||||
let state = Self(Rc::new(DBusStateInner {
|
||||
evlh: evlh.clone(),
|
||||
executor,
|
||||
session_conn: async_once_cell::OnceCell::new(),
|
||||
system_conn: async_once_cell::OnceCell::new(),
|
||||
session_conn,
|
||||
system_conn,
|
||||
a11y_keyboard_monitor: RefCell::new(None),
|
||||
}));
|
||||
evlh.insert_source(source, |_, _, _| {}).unwrap();
|
||||
|
|
@ -63,18 +65,13 @@ impl DBusState {
|
|||
RefMut::filter_map(self.0.a11y_keyboard_monitor.borrow_mut(), |x| x.as_mut()).ok()
|
||||
}
|
||||
|
||||
// TODO Lazy async init when we don't have anything blocking main thread
|
||||
async fn session_conn(&self) -> zbus::Result<&zbus::Connection> {
|
||||
self.0
|
||||
.session_conn
|
||||
.get_or_try_init(zbus::Connection::session())
|
||||
.await
|
||||
self.0.session_conn.as_ref().map_err(|err| err.clone())
|
||||
}
|
||||
|
||||
async fn system_conn(&self) -> zbus::Result<&zbus::Connection> {
|
||||
self.0
|
||||
.system_conn
|
||||
.get_or_try_init(zbus::Connection::system())
|
||||
.await
|
||||
self.0.system_conn.as_ref().map_err(|err| err.clone())
|
||||
}
|
||||
|
||||
fn spawn(&self, fut: impl Future<Output = ()> + 'static) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue