From 401b8b5759e3f136cb462faa667e023d7ecaa6a8 Mon Sep 17 00:00:00 2001 From: Gavin Li Date: Sat, 15 Jan 2022 00:21:02 -0800 Subject: [PATCH] Properly implement TEventLoop::poll for AvahiEventLoop As of Avahi 0.7, the sleep_time arg passed to `avahi_simple_poll_iterate()` is utilized. Properly implementing this reduces CPU spent polling while improving responsiveness. --- zeroconf/src/linux/event_loop.rs | 10 +++++----- zeroconf/src/linux/poll.rs | 11 +++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/zeroconf/src/linux/event_loop.rs b/zeroconf/src/linux/event_loop.rs index 65754a0..e96970c 100644 --- a/zeroconf/src/linux/event_loop.rs +++ b/zeroconf/src/linux/event_loop.rs @@ -3,6 +3,7 @@ use super::poll::ManagedAvahiSimplePoll; use crate::event_loop::TEventLoop; use crate::Result; +use std::convert::TryInto; use std::marker::PhantomData; use std::sync::Arc; use std::time::Duration; @@ -16,10 +17,9 @@ pub struct AvahiEventLoop<'a> { impl<'a> TEventLoop for AvahiEventLoop<'a> { /// Polls for new events. /// - /// Internally calls `ManagedAvahiSimplePoll::iterate(0)`, the `timeout` parameter does not - /// currently do anything in the Avahi implementation. - fn poll(&self, _timeout: Duration) -> Result<()> { - self.poll.iterate(0); - Ok(()) + /// The `timeout` parameter defines the maximum time to sleep, but it will return earlier if + /// an event occurs. + fn poll(&self, timeout: Duration) -> Result<()> { + self.poll.iterate(timeout.as_millis().try_into().unwrap_or(-1)) } } diff --git a/zeroconf/src/linux/poll.rs b/zeroconf/src/linux/poll.rs index 2cef826..527d5bd 100644 --- a/zeroconf/src/linux/poll.rs +++ b/zeroconf/src/linux/poll.rs @@ -38,8 +38,15 @@ impl ManagedAvahiSimplePoll { /// Delegate function for [`avahi_simple_poll_iterate()`]. /// /// [`avahi_simple_poll_iterate()`]: https://avahi.org/doxygen/html/simple-watch_8h.html#ad5b7c9d3b7a6584d609241ee6f472a2e - pub fn iterate(&self, sleep_time: i32) { - unsafe { avahi_simple_poll_iterate(self.0, sleep_time) }; + pub fn iterate(&self, sleep_time: i32) -> Result<()> { + let err = unsafe { avahi_simple_poll_iterate(self.0, sleep_time) }; + if err < 0 { + avahi!(err, "AvahiSimplePoll poll failed") + } else if err > 0 { + Err("AvahiSimplePoll requested quit".into()) + } else { + Ok(()) + } } pub(super) fn inner(&self) -> *mut AvahiSimplePoll {