From b2c9e76663b8f1f808b0d8e54db5db6ac316c173 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 7 Sep 2023 19:47:50 -0700 Subject: [PATCH] client: Implement `AsFd` for `Connection` and `EventQueue` This helps for using an `Generic` with calloop 0.11. --- wayland-backend/CHANGELOG.md | 4 ++++ wayland-backend/src/client_api.rs | 6 ++++++ wayland-backend/src/rs/client_impl/mod.rs | 7 +++++++ wayland-backend/src/sys/client_impl/mod.rs | 11 +++++++++++ wayland-client/CHANGELOG.md | 5 +++++ wayland-client/src/conn.rs | 9 ++++++++- wayland-client/src/event_queue.rs | 9 ++++++++- 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/wayland-backend/CHANGELOG.md b/wayland-backend/CHANGELOG.md index 204d866ecef..2d1edf4aa4e 100644 --- a/wayland-backend/CHANGELOG.md +++ b/wayland-backend/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +#### Additions + +- client: Add `Backend::poll_fd` to return fd for polling + ## 0.3.0 -- 2023-09-02 #### Breaking change diff --git a/wayland-backend/src/client_api.rs b/wayland-backend/src/client_api.rs index 02bcaa7e044..9908baa6548 100644 --- a/wayland-backend/src/client_api.rs +++ b/wayland-backend/src/client_api.rs @@ -181,6 +181,12 @@ impl Backend { self.backend.flush() } + /// Access the Wayland socket FD for polling + #[inline] + pub fn poll_fd(&self) -> BorrowedFd { + self.backend.poll_fd() + } + /// Get the object ID for the `wl_display` #[inline] pub fn display_id(&self) -> ObjectId { diff --git a/wayland-backend/src/rs/client_impl/mod.rs b/wayland-backend/src/rs/client_impl/mod.rs index 128d436050d..97047f44585 100644 --- a/wayland-backend/src/rs/client_impl/mod.rs +++ b/wayland-backend/src/rs/client_impl/mod.rs @@ -191,6 +191,13 @@ impl InnerBackend { } Ok(()) } + + pub fn poll_fd(&self) -> BorrowedFd { + let raw_fd = self.state.lock_protocol().socket.as_raw_fd(); + // This allows the lifetime of the BorrowedFd to be tied to &self rather than the lock guard, + // which is the real safety concern + unsafe { BorrowedFd::borrow_raw(raw_fd) } + } } #[derive(Debug)] diff --git a/wayland-backend/src/sys/client_impl/mod.rs b/wayland-backend/src/sys/client_impl/mod.rs index 9787903cfa6..7a48f8ce259 100644 --- a/wayland-backend/src/sys/client_impl/mod.rs +++ b/wayland-backend/src/sys/client_impl/mod.rs @@ -293,6 +293,17 @@ impl InnerBackend { } } + pub fn poll_fd(&self) -> BorrowedFd { + let guard = self.lock_state(); + unsafe { + BorrowedFd::borrow_raw(ffi_dispatch!( + wayland_client_handle(), + wl_display_get_fd, + guard.display + )) + } + } + pub fn dispatch_inner_queue(&self) -> Result { self.inner.dispatch_lock.lock().unwrap().dispatch_pending(self.inner.clone()) } diff --git a/wayland-client/CHANGELOG.md b/wayland-client/CHANGELOG.md index 0976dcb4216..bad26cb7eb1 100644 --- a/wayland-client/CHANGELOG.md +++ b/wayland-client/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +#### Additions + +- Implement `AsFd` for `Connection` and `EventQueue` so they can easily be used in a + `calloop` source. + ## 0.31.0 -- 2023-09-02 #### Breaking changes diff --git a/wayland-client/src/conn.rs b/wayland-client/src/conn.rs index 6812bfc393f..3dc89af8796 100644 --- a/wayland-client/src/conn.rs +++ b/wayland-client/src/conn.rs @@ -3,7 +3,7 @@ use std::{ io::ErrorKind, os::unix::io::OwnedFd, os::unix::net::UnixStream, - os::unix::prelude::{AsRawFd, FromRawFd}, + os::unix::prelude::{AsFd, AsRawFd, BorrowedFd, FromRawFd}, path::PathBuf, sync::{ atomic::{AtomicBool, Ordering}, @@ -273,6 +273,13 @@ impl fmt::Display for ConnectError { } } +impl AsFd for Connection { + /// Provides fd from [`Backend::poll_fd`] for polling. + fn as_fd(&self) -> BorrowedFd<'_> { + self.backend.poll_fd() + } +} + /* wl_callback object data for wl_display.sync */ diff --git a/wayland-client/src/event_queue.rs b/wayland-client/src/event_queue.rs index 2d2a729b6e9..35fdca70b14 100644 --- a/wayland-client/src/event_queue.rs +++ b/wayland-client/src/event_queue.rs @@ -2,7 +2,7 @@ use std::any::Any; use std::collections::VecDeque; use std::convert::Infallible; use std::marker::PhantomData; -use std::os::unix::io::OwnedFd; +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; use std::sync::{atomic::Ordering, Arc, Condvar, Mutex}; use std::task; @@ -349,6 +349,13 @@ impl std::fmt::Debug for EventQueue { } } +impl AsFd for EventQueue { + /// Provides fd from [`Backend::poll_fd`] for polling. + fn as_fd(&self) -> BorrowedFd<'_> { + self.conn.as_fd() + } +} + impl EventQueue { pub(crate) fn new(conn: Connection) -> Self { let inner = Arc::new(Mutex::new(EventQueueInner {