1
0
Fork 0
forked from wry/wry

object_drop_queue: add new utility

This commit is contained in:
Julian Orth 2026-03-13 12:56:17 +01:00
parent f289eb8424
commit 85b9b7222d
4 changed files with 91 additions and 0 deletions

View file

@ -72,6 +72,7 @@ use {
fdcloser::FdCloser,
nice::{did_elevate_scheduler, elevate_scheduler},
numcell::NumCell,
object_drop_queue::ObjectDropQueue,
oserror::OsError,
queue::AsyncQueue,
rc_eq::RcEq,
@ -390,6 +391,7 @@ fn start_compositor2(
supports_presentation_feedback: Default::default(),
eventfd_cache,
lazy_event_sources: Default::default(),
bo_drop_queue: Rc::new(ObjectDropQueue::new(&ring)),
});
state.tracker.register(ClientId::from_raw(0));
create_dummy_output(&state);

View file

@ -1,6 +1,7 @@
use {
crate::{
acceptor::Acceptor,
allocator::BufferObject,
async_engine::{AsyncEngine, SpawnedFuture},
backend::{
Backend, BackendConnectorState, BackendConnectorStateSerials, BackendDrmDevice,
@ -115,6 +116,7 @@ use {
hash_map_ext::HashMapExt,
linkedlist::LinkedList,
numcell::NumCell,
object_drop_queue::ObjectDropQueue,
queue::AsyncQueue,
refcounted::RefCounted,
run_toplevel::RunToplevel,
@ -292,6 +294,7 @@ pub struct State {
pub supports_presentation_feedback: Cell<bool>,
pub eventfd_cache: Rc<EventfdCache>,
pub lazy_event_sources: Rc<LazyEventSources>,
pub bo_drop_queue: Rc<ObjectDropQueue<Rc<dyn BufferObject>>>,
}
// impl Drop for State {
@ -1154,6 +1157,7 @@ impl State {
self.wait_for_syncobj.clear();
self.xdg_surface_configure_events.clear();
self.lazy_event_sources.clear();
self.bo_drop_queue.kill();
}
pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) {

View file

@ -31,6 +31,7 @@ pub mod nice;
pub mod nonblock;
pub mod num_cpus;
pub mod numcell;
pub mod object_drop_queue;
pub mod on_change;
pub mod on_drop_event;
pub mod once;

View file

@ -0,0 +1,84 @@
use {
crate::{
io_uring::{IoUring, PendingPoll, PollCallback},
utils::{errorfmt::ErrorFmt, oserror::OsError, stack::Stack},
},
std::{
cell::{Cell, RefCell},
rc::Rc,
},
uapi::{OwnedFd, c::c_short},
};
pub struct ObjectDropQueue<T> {
ring: Rc<IoUring>,
killed: Cell<bool>,
pending: RefCell<Vec<Option<(T, PendingPoll)>>>,
stack: Stack<Rc<Pollable<T>>>,
}
struct Pollable<T> {
queue: Rc<ObjectDropQueue<T>>,
idx: usize,
}
impl<T> ObjectDropQueue<T> {
pub fn new(ring: &Rc<IoUring>) -> Self {
Self {
ring: ring.clone(),
killed: Default::default(),
pending: Default::default(),
stack: Default::default(),
}
}
#[expect(dead_code)]
pub fn push(self: &Rc<Self>, fd: &Rc<OwnedFd>, t: T)
where
T: 'static,
{
if self.killed.get() {
return;
}
let pending = &mut *self.pending.borrow_mut();
let pollable = match self.stack.pop() {
Some(p) => p,
None => {
let pollable = Rc::new(Pollable {
queue: self.clone(),
idx: pending.len(),
});
pending.push(None);
pollable
}
};
let idx = pollable.idx;
match self.ring.readable_external(fd, pollable) {
Ok(p) => {
pending[idx] = Some((t, p));
}
Err(e) => {
log::error!("Could not register object: {}", ErrorFmt(e));
}
}
}
pub fn kill(&self) {
self.killed.set(true);
self.pending.take();
self.stack.take();
}
}
impl<T> PollCallback for Pollable<T> {
fn completed(self: Rc<Self>, res: Result<c_short, OsError>) {
if let Err(e) = res {
log::error!("Could not wait for fd to become readable: {}", ErrorFmt(e));
}
let q = &self.queue;
if !q.killed.get() {
q.pending.borrow_mut()[self.idx] = None;
q.stack.push(self.clone());
}
}
}