diff --git a/wayland-backend/src/server_api.rs b/wayland-backend/src/server_api.rs index 6e3565db1c0..b3314870bd3 100644 --- a/wayland-backend/src/server_api.rs +++ b/wayland-backend/src/server_api.rs @@ -249,6 +249,7 @@ impl WeakHandle { /// Try to upgrade this weak handle to a [`Handle`] /// /// Returns `None` if the associated backend was already dropped. + #[inline] pub fn upgrade(&self) -> Option { self.handle.upgrade().map(|handle| Handle { handle }) } @@ -256,6 +257,7 @@ impl WeakHandle { impl Handle { /// Get a [`WeakHandle`] from this handle + #[inline] pub fn downgrade(&self) -> WeakHandle { WeakHandle { handle: self.handle.downgrade() } } diff --git a/wayland-scanner/src/server_gen.rs b/wayland-scanner/src/server_gen.rs index 8f4a27f4d12..af13af35e52 100644 --- a/wayland-scanner/src/server_gen.rs +++ b/wayland-scanner/src/server_gen.rs @@ -83,6 +83,7 @@ fn generate_objects_for(interface: &Interface) -> TokenStream { } impl std::cmp::PartialEq for #iface_name { + #[inline] fn eq(&self, other: &#iface_name) -> bool { self.id == other.id } @@ -91,18 +92,21 @@ fn generate_objects_for(interface: &Interface) -> TokenStream { impl std::cmp::Eq for #iface_name {} impl PartialEq> for #iface_name { + #[inline] fn eq(&self, other: &Weak<#iface_name>) -> bool { self.id == other.id() } } impl std::borrow::Borrow for #iface_name { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for #iface_name { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } diff --git a/wayland-scanner/tests/scanner_assets/test-server-code.rs b/wayland-scanner/tests/scanner_assets/test-server-code.rs index e6773cbc24a..495fe6d5eaa 100644 --- a/wayland-scanner/tests/scanner_assets/test-server-code.rs +++ b/wayland-scanner/tests/scanner_assets/test-server-code.rs @@ -54,22 +54,26 @@ pub mod wl_callback { handle: WeakHandle, } impl std::cmp::PartialEq for WlCallback { + #[inline] fn eq(&self, other: &WlCallback) -> bool { self.id == other.id } } impl std::cmp::Eq for WlCallback {} impl PartialEq> for WlCallback { + #[inline] fn eq(&self, other: &Weak) -> bool { self.id == other.id() } } impl std::borrow::Borrow for WlCallback { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for WlCallback { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } @@ -316,22 +320,26 @@ pub mod test_global { handle: WeakHandle, } impl std::cmp::PartialEq for TestGlobal { + #[inline] fn eq(&self, other: &TestGlobal) -> bool { self.id == other.id } } impl std::cmp::Eq for TestGlobal {} impl PartialEq> for TestGlobal { + #[inline] fn eq(&self, other: &Weak) -> bool { self.id == other.id() } } impl std::borrow::Borrow for TestGlobal { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for TestGlobal { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } @@ -822,22 +830,26 @@ pub mod secondary { handle: WeakHandle, } impl std::cmp::PartialEq for Secondary { + #[inline] fn eq(&self, other: &Secondary) -> bool { self.id == other.id } } impl std::cmp::Eq for Secondary {} impl PartialEq> for Secondary { + #[inline] fn eq(&self, other: &Weak) -> bool { self.id == other.id() } } impl std::borrow::Borrow for Secondary { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for Secondary { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } @@ -981,22 +993,26 @@ pub mod tertiary { handle: WeakHandle, } impl std::cmp::PartialEq for Tertiary { + #[inline] fn eq(&self, other: &Tertiary) -> bool { self.id == other.id } } impl std::cmp::Eq for Tertiary {} impl PartialEq> for Tertiary { + #[inline] fn eq(&self, other: &Weak) -> bool { self.id == other.id() } } impl std::borrow::Borrow for Tertiary { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for Tertiary { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } @@ -1140,22 +1156,26 @@ pub mod quad { handle: WeakHandle, } impl std::cmp::PartialEq for Quad { + #[inline] fn eq(&self, other: &Quad) -> bool { self.id == other.id } } impl std::cmp::Eq for Quad {} impl PartialEq> for Quad { + #[inline] fn eq(&self, other: &Weak) -> bool { self.id == other.id() } } impl std::borrow::Borrow for Quad { + #[inline] fn borrow(&self) -> &ObjectId { &self.id } } impl std::hash::Hash for Quad { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state) } diff --git a/wayland-server/CHANGELOG.md b/wayland-server/CHANGELOG.md index c0c420ea1d4..2440948b1e1 100644 --- a/wayland-server/CHANGELOG.md +++ b/wayland-server/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +#### Additions + +- Add `Weak::is_alive` allowing to check if a resource is still alive. + ## 0.31.1 -- 2024-01-29 - Dropped `nix` dependency in favor of `rustix` diff --git a/wayland-server/src/lib.rs b/wayland-server/src/lib.rs index 7526f430a46..74f8744a58a 100644 --- a/wayland-server/src/lib.rs +++ b/wayland-server/src/lib.rs @@ -160,6 +160,7 @@ pub trait Resource: Clone + std::fmt::Debug + Sized { fn version(&self) -> u32; /// Checks if the Wayland object associated with this proxy is still alive + #[inline] fn is_alive(&self) -> bool { if let Some(handle) = self.handle().upgrade() { handle.object_info(self.id()).is_ok() @@ -231,6 +232,7 @@ pub trait Resource: Clone + std::fmt::Debug + Sized { /// /// This can be of use if you need to store resources in the used data of other objects and want /// to be sure to avoid reference cycles that would cause memory leaks. + #[inline] fn downgrade(&self) -> Weak { Weak { handle: self.handle().clone(), id: self.id(), _iface: std::marker::PhantomData } } @@ -285,6 +287,7 @@ impl Weak { /// This will fail if either: /// - the object represented by this handle has already been destroyed at the protocol level /// - the Wayland connection has already been closed + #[inline] pub fn upgrade(&self) -> Result { let handle = self.handle.upgrade().ok_or(InvalidId)?; // Check if the object has been destroyed @@ -293,6 +296,19 @@ impl Weak { I::from_id(&d_handle, self.id.clone()) } + /// Check if this resource is still alive + /// + /// This will return `false` if either: + /// - the object represented by this handle has already been destroyed at the protocol level + /// - the Wayland connection has already been closed + #[inline] + pub fn is_alive(&self) -> bool { + let Some(handle) = self.handle.upgrade() else { + return false; + }; + handle.object_info(self.id.clone()).is_ok() + } + /// The underlying [`ObjectId`] pub fn id(&self) -> ObjectId { self.id.clone() @@ -300,6 +316,7 @@ impl Weak { } impl PartialEq for Weak { + #[inline] fn eq(&self, other: &Self) -> bool { self.id == other.id } @@ -308,12 +325,14 @@ impl PartialEq for Weak { impl Eq for Weak {} impl Hash for Weak { + #[inline] fn hash(&self, state: &mut H) { self.id.hash(state); } } impl PartialEq for Weak { + #[inline] fn eq(&self, other: &I) -> bool { self.id == other.id() }