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,
|
fdcloser::FdCloser,
|
||||||
nice::{did_elevate_scheduler, elevate_scheduler},
|
nice::{did_elevate_scheduler, elevate_scheduler},
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
|
object_drop_queue::ObjectDropQueue,
|
||||||
oserror::OsError,
|
oserror::OsError,
|
||||||
queue::AsyncQueue,
|
queue::AsyncQueue,
|
||||||
rc_eq::RcEq,
|
rc_eq::RcEq,
|
||||||
|
|
@ -390,6 +391,7 @@ fn start_compositor2(
|
||||||
supports_presentation_feedback: Default::default(),
|
supports_presentation_feedback: Default::default(),
|
||||||
eventfd_cache,
|
eventfd_cache,
|
||||||
lazy_event_sources: Default::default(),
|
lazy_event_sources: Default::default(),
|
||||||
|
bo_drop_queue: Rc::new(ObjectDropQueue::new(&ring)),
|
||||||
});
|
});
|
||||||
state.tracker.register(ClientId::from_raw(0));
|
state.tracker.register(ClientId::from_raw(0));
|
||||||
create_dummy_output(&state);
|
create_dummy_output(&state);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
acceptor::Acceptor,
|
acceptor::Acceptor,
|
||||||
|
allocator::BufferObject,
|
||||||
async_engine::{AsyncEngine, SpawnedFuture},
|
async_engine::{AsyncEngine, SpawnedFuture},
|
||||||
backend::{
|
backend::{
|
||||||
Backend, BackendConnectorState, BackendConnectorStateSerials, BackendDrmDevice,
|
Backend, BackendConnectorState, BackendConnectorStateSerials, BackendDrmDevice,
|
||||||
|
|
@ -115,6 +116,7 @@ use {
|
||||||
hash_map_ext::HashMapExt,
|
hash_map_ext::HashMapExt,
|
||||||
linkedlist::LinkedList,
|
linkedlist::LinkedList,
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
|
object_drop_queue::ObjectDropQueue,
|
||||||
queue::AsyncQueue,
|
queue::AsyncQueue,
|
||||||
refcounted::RefCounted,
|
refcounted::RefCounted,
|
||||||
run_toplevel::RunToplevel,
|
run_toplevel::RunToplevel,
|
||||||
|
|
@ -292,6 +294,7 @@ pub struct State {
|
||||||
pub supports_presentation_feedback: Cell<bool>,
|
pub supports_presentation_feedback: Cell<bool>,
|
||||||
pub eventfd_cache: Rc<EventfdCache>,
|
pub eventfd_cache: Rc<EventfdCache>,
|
||||||
pub lazy_event_sources: Rc<LazyEventSources>,
|
pub lazy_event_sources: Rc<LazyEventSources>,
|
||||||
|
pub bo_drop_queue: Rc<ObjectDropQueue<Rc<dyn BufferObject>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Drop for State {
|
// impl Drop for State {
|
||||||
|
|
@ -1154,6 +1157,7 @@ impl State {
|
||||||
self.wait_for_syncobj.clear();
|
self.wait_for_syncobj.clear();
|
||||||
self.xdg_surface_configure_events.clear();
|
self.xdg_surface_configure_events.clear();
|
||||||
self.lazy_event_sources.clear();
|
self.lazy_event_sources.clear();
|
||||||
|
self.bo_drop_queue.kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) {
|
pub fn remove_toplevel_id(&self, id: ToplevelIdentifier) {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ pub mod nice;
|
||||||
pub mod nonblock;
|
pub mod nonblock;
|
||||||
pub mod num_cpus;
|
pub mod num_cpus;
|
||||||
pub mod numcell;
|
pub mod numcell;
|
||||||
|
pub mod object_drop_queue;
|
||||||
pub mod on_change;
|
pub mod on_change;
|
||||||
pub mod on_drop_event;
|
pub mod on_drop_event;
|
||||||
pub mod once;
|
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