Skip to content

Commit

Permalink
shm: close client buffers in the cpu worker
Browse files Browse the repository at this point in the history
  • Loading branch information
mahkoh committed Sep 8, 2024
1 parent c87bc69 commit 3d0de5a
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 16 deletions.
7 changes: 4 additions & 3 deletions src/cli/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,10 @@ impl Input {
async fn handle_keymap(&self, input: JayInputId) -> Vec<u8> {
let data = Rc::new(RefCell::new(Vec::new()));
jay_input::Keymap::handle(&self.tc, input, data.clone(), |d, map| {
let mem =
Rc::new(ClientMem::new(&map.keymap, map.keymap_len as _, true, None).unwrap())
.offset(0);
let mem = Rc::new(
ClientMem::new(&map.keymap, map.keymap_len as _, true, None, None).unwrap(),
)
.offset(0);
mem.read(d.borrow_mut().deref_mut()).unwrap();
});
self.tc.round_trip().await;
Expand Down
55 changes: 49 additions & 6 deletions src/clientmem.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
use {
crate::{client::Client, utils::vec_ext::VecExt},
crate::{
client::Client,
cpu_worker::{AsyncCpuWork, CpuJob, CpuWork, CpuWorker},
utils::vec_ext::VecExt,
},
std::{
cell::Cell,
mem::MaybeUninit,
mem::{ManuallyDrop, MaybeUninit},
ptr,
rc::Rc,
sync::atomic::{compiler_fence, Ordering},
Expand All @@ -25,10 +29,11 @@ pub enum ClientMemError {
}

pub struct ClientMem {
fd: Rc<OwnedFd>,
fd: ManuallyDrop<Rc<OwnedFd>>,
failed: Cell<bool>,
sigbus_impossible: bool,
data: *const [Cell<u8>],
cpu: Option<Rc<CpuWorker>>,
}

#[derive(Clone)]
Expand All @@ -44,6 +49,7 @@ impl ClientMem {
len: usize,
read_only: bool,
client: Option<&Client>,
cpu: Option<&Rc<CpuWorker>>,
) -> Result<Self, ClientMemError> {
let mut sigbus_impossible = false;
if let Ok(seals) = uapi::fcntl_get_seals(fd.raw()) {
Expand Down Expand Up @@ -78,10 +84,11 @@ impl ClientMem {
}
};
Ok(Self {
fd: fd.clone(),
fd: ManuallyDrop::new(fd.clone()),
failed: Cell::new(false),
sigbus_impossible,
data,
cpu: cpu.cloned(),
})
}

Expand Down Expand Up @@ -155,8 +162,17 @@ impl ClientMemOffset {

impl Drop for ClientMem {
fn drop(&mut self) {
unsafe {
c::munmap(self.data as _, self.len());
let fd = unsafe { ManuallyDrop::take(&mut self.fd) };
if let Some(cpu) = &self.cpu {
let pending = cpu.submit(Box::new(CloseMemWork {
fd: Rc::try_unwrap(fd).ok(),
data: self.data,
}));
pending.detach();
} else {
unsafe {
c::munmap(self.data as _, self.len());
}
}
}
}
Expand Down Expand Up @@ -219,3 +235,30 @@ pub fn init() -> Result<(), ClientMemError> {
}
}
}

struct CloseMemWork {
fd: Option<OwnedFd>,
data: *const [Cell<u8>],
}

unsafe impl Send for CloseMemWork {}

impl CpuJob for CloseMemWork {
fn work(&mut self) -> &mut dyn CpuWork {
self
}

fn completed(self: Box<Self>) {
// nothing
}
}

impl CpuWork for CloseMemWork {
fn run(&mut self) -> Option<Box<dyn AsyncCpuWork>> {
self.fd.take();
unsafe {
c::munmap(self.data as _, self.data.len());
}
None
}
}
1 change: 0 additions & 1 deletion src/cpu_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ pub enum CpuWorkerError {
}

impl PendingJob {
#[expect(dead_code)]
pub fn detach(self) {
match self.job_data.state.get() {
PendingJobState::Waiting => {
Expand Down
9 changes: 8 additions & 1 deletion src/ifs/jay_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,14 @@ impl JayInput {
where
F: FnOnce(&Rc<XkbKeymap>) -> Result<(), JayInputError>,
{
let cm = Rc::new(ClientMem::new(keymap, len as _, true, Some(&self.client))?).offset(0);
let cm = Rc::new(ClientMem::new(
keymap,
len as _,
true,
Some(&self.client),
None,
)?)
.offset(0);
let mut map = vec![];
cm.read(&mut map)?;
self.or_error(|| {
Expand Down
12 changes: 9 additions & 3 deletions src/ifs/wl_seat/zwp_virtual_keyboard_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,15 @@ impl ZwpVirtualKeyboardV1RequestHandler for ZwpVirtualKeyboardV1 {
if req.size > MAX_SIZE {
return Err(ZwpVirtualKeyboardV1Error::OversizedKeymap);
}
let client_mem = ClientMem::new(&req.fd, req.size as usize - 1, true, Some(&self.client))
.map(Rc::new)
.map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?;
let client_mem = ClientMem::new(
&req.fd,
req.size as usize - 1,
true,
Some(&self.client),
None,
)
.map(Rc::new)
.map_err(ZwpVirtualKeyboardV1Error::MapKeymap)?;
let mut map = vec![];
client_mem
.offset(0)
Expand Down
9 changes: 8 additions & 1 deletion src/ifs/wl_shm_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ impl WlShmPool {
Ok(Self {
id,
client: client.clone(),
mem: CloneCell::new(Rc::new(ClientMem::new(&fd, len, false, Some(client))?)),
mem: CloneCell::new(Rc::new(ClientMem::new(
&fd,
len,
false,
Some(client),
Some(&client.state.cpu_worker),
)?)),
fd,
tracker: Default::default(),
version,
Expand Down Expand Up @@ -86,6 +92,7 @@ impl WlShmPoolRequestHandler for WlShmPool {
req.size as usize,
false,
Some(&self.client),
Some(&self.client.state.cpu_worker),
)?));
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion src/it/tests/t0040_virtual_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
}

fn read_keymap(fd: &Rc<OwnedFd>, size: usize) -> String {
let client_mem = ClientMem::new(fd, size - 1, true, None).unwrap();
let client_mem = ClientMem::new(fd, size - 1, true, None, None).unwrap();
let client_mem = Rc::new(client_mem).offset(0);
let mut v = vec![];
client_mem.read(&mut v).unwrap();
Expand Down

0 comments on commit 3d0de5a

Please sign in to comment.