Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland-server: alive check for Weak #720

Merged
merged 2 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions wayland-backend/src/server_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,15 @@ 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<Handle> {
self.handle.upgrade().map(|handle| Handle { handle })
}
}

impl Handle {
/// Get a [`WeakHandle`] from this handle
#[inline]
pub fn downgrade(&self) -> WeakHandle {
WeakHandle { handle: self.handle.downgrade() }
}
Expand Down
4 changes: 4 additions & 0 deletions wayland-scanner/src/server_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -91,18 +92,21 @@ fn generate_objects_for(interface: &Interface) -> TokenStream {
impl std::cmp::Eq for #iface_name {}

impl PartialEq<Weak<#iface_name>> for #iface_name {
#[inline]
fn eq(&self, other: &Weak<#iface_name>) -> bool {
self.id == other.id()
}
}

impl std::borrow::Borrow<ObjectId> for #iface_name {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}

impl std::hash::Hash for #iface_name {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down
20 changes: 20 additions & 0 deletions wayland-scanner/tests/scanner_assets/test-server-code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Weak<WlCallback>> for WlCallback {
#[inline]
fn eq(&self, other: &Weak<WlCallback>) -> bool {
self.id == other.id()
}
}
impl std::borrow::Borrow<ObjectId> for WlCallback {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}
impl std::hash::Hash for WlCallback {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down Expand Up @@ -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<Weak<TestGlobal>> for TestGlobal {
#[inline]
fn eq(&self, other: &Weak<TestGlobal>) -> bool {
self.id == other.id()
}
}
impl std::borrow::Borrow<ObjectId> for TestGlobal {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}
impl std::hash::Hash for TestGlobal {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down Expand Up @@ -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<Weak<Secondary>> for Secondary {
#[inline]
fn eq(&self, other: &Weak<Secondary>) -> bool {
self.id == other.id()
}
}
impl std::borrow::Borrow<ObjectId> for Secondary {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}
impl std::hash::Hash for Secondary {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down Expand Up @@ -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<Weak<Tertiary>> for Tertiary {
#[inline]
fn eq(&self, other: &Weak<Tertiary>) -> bool {
self.id == other.id()
}
}
impl std::borrow::Borrow<ObjectId> for Tertiary {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}
impl std::hash::Hash for Tertiary {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down Expand Up @@ -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<Weak<Quad>> for Quad {
#[inline]
fn eq(&self, other: &Weak<Quad>) -> bool {
self.id == other.id()
}
}
impl std::borrow::Borrow<ObjectId> for Quad {
#[inline]
fn borrow(&self) -> &ObjectId {
&self.id
}
}
impl std::hash::Hash for Quad {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
Expand Down
4 changes: 4 additions & 0 deletions wayland-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
19 changes: 19 additions & 0 deletions wayland-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
//! [`Backend`](crate::backend::Backend) using [`Display::backend()`], and then invoke
//! `Backend::display_ptr().
//! - The `*mut wl_resource` pointers for the objects you need to share, by first getting the
//! [`ObjectId`](crate::backend::ObjectId) using the [`Resource::id()`] method, and then

Check warning on line 69 in wayland-server/src/lib.rs

View workflow job for this annotation

GitHub Actions / Documentation on Github Pages

redundant explicit link target
//! the `ObjectId::as_ptr()` method.
//!
//! If you need to receive pointers from FFI, you can make [`ObjectId`]s from the `*mut wl_resource` pointers
Expand Down Expand Up @@ -160,6 +160,7 @@
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()
Expand Down Expand Up @@ -231,6 +232,7 @@
///
/// 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<Self> {
Weak { handle: self.handle().clone(), id: self.id(), _iface: std::marker::PhantomData }
}
Expand Down Expand Up @@ -285,6 +287,7 @@
/// 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<I, InvalidId> {
let handle = self.handle.upgrade().ok_or(InvalidId)?;
// Check if the object has been destroyed
Expand All @@ -293,13 +296,27 @@
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()
}
}

impl<I> PartialEq for Weak<I> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
Expand All @@ -308,12 +325,14 @@
impl<I> Eq for Weak<I> {}

impl<I> Hash for Weak<I> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}

impl<I: Resource> PartialEq<I> for Weak<I> {
#[inline]
fn eq(&self, other: &I) -> bool {
self.id == other.id()
}
Expand Down
Loading