Service with refresh function called by thread hangs on occasion
I have a service that needs to poll values in the background and therefore cannot wait for the next event to come in from a client. So I created another thread that calls a refresh function once a second, similar to this using zbus 2.0.0-beta:
use std::convert::TryInto;
use std::error::Error;
use zbus::{dbus_interface, fdo};
struct Greeter {
count: u64,
}
#[dbus_interface(name = "org.zbus.MyGreeter1")]
impl Greeter {
fn refresh(&mut self) {
self.count += 1;
}
#[dbus_interface(property)]
fn count(&self) -> u64 {
self.count
}
}
fn main() -> Result<(), Box<dyn Error>> {
let connection = zbus::Connection::new_session()?;
fdo::DBusProxy::new(&connection)?.request_name(
"org.zbus.MyGreeter",
fdo::RequestNameFlags::ReplaceExisting.into(),
)?;
let mut object_server = zbus::ObjectServer::new(&connection);
let greeter = Greeter { count: 0 };
object_server.at(&"/org/zbus/MyGreeter".try_into()?, greeter)?;
let _t = std::thread::spawn(move || loop {
std::thread::sleep(std::time::Duration::from_secs(1));
connection
.call_method(
Some("org.zbus.MyGreeter"),
"/org/zbus/MyGreeter",
Some("org.zbus.MyGreeter1"),
"Refresh",
&(),
)
.unwrap();
});
loop {
if let Err(err) = object_server.try_handle_next() {
eprintln!("{}", err);
}
}
}
To get the hangs to happen (or to make them noticeable?), run for example:
$ for i in $(seq 1000); do busctl --user get-property org.zbus.MyGreeter /org/zbus/MyGreeter org.zbus.MyGreeter1 Count; done
...
t 12
t 12
t 12
t 12
t 12
Failed to get property Count on interface org.zbus.MyGreeter1: Connection timed out
t 13
t 13
t 13
t 13
t 13
t 13
t 13
...
I could not get this to happen if I comment out the thread in the main function.