object_drop_queue: add new utility
This commit is contained in:
parent
f289eb8424
commit
85b9b7222d
4 changed files with 91 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
84
src/utils/object_drop_queue.rs
Normal file
84
src/utils/object_drop_queue.rs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue